Правильный способ инициализировать хранилище HashMap HashMap и может держать различные типы значений?


Итак, у меня есть два вопроса о HashMaps в Java:

  1. Как правильно инициализировать HashMap? Я думаю, что это может быть лучше в моей ситуации, чтобы использовать:

    HashMap x = new HashMap();
    

    но Eclipse продолжает предлагать мне использовать:

    HashMap<something, something> map = new HashMap();
    

    что лучше?

  2. может a HashMap разные типы объектов/типов данных в качестве значений? Например, будет ли это работать и быть в порядке:

    map.put("one", 1);
    map.put("two", {1, 2});
    map.put("three", "hello");
    

    в первый put(), Я хочу int как значение, во втором an int[], и третью строку. Это нормально делать на Java с HashMaps? Кроме того, можно ли хранить a HashMap как значение в пределах HashMap?

8 58

8 ответов:

это действительно зависит от того, какой тип безопасности нужен. Не общий способ сделать это лучше всего сделать так:

 Map x = new HashMap();

отметим, что x введен Map. это значительно упрощает изменение реализаций (до TreeMap или LinkedHashMap) в будущем.

вы можете использовать дженерики для обеспечения определенного уровня безопасности типа:

Map<String, Object> x = new HashMap<String, Object>();

в Java 7 и позже вы можете сделать

Map<String, Object> x = new HashMap<>();

выше, в то время как более подробный, избегает предупреждение компилятора. В этом случае содержание HashMap может быть Object, так что может быть Integer,int[] и т. д. что вы делаете.

если вы все еще используете Java 6, Гуава Библиотеки (хотя это достаточно легко сделать самостоятельно) имеет метод, называемый newHashMap() что позволяет избежать необходимости дублировать общую информацию о наборе текста, когда вы делаете new. Он выводит тип из объявления переменной (это функция Java не доступно на конструкторах до Java 7).

кстати, когда вы добавляете int или другой примитив, Java автоматически загружает его. Это означает, что код эквивалентен:

 x.put("one", Integer.valueOf(1));

вы можете, конечно, поставить HashMap как значение в другой HashMap, но я думаю, что есть проблемы, если вы делаете это рекурсивно (то есть ставите HashMap как значение само по себе).

это изменение сделано с Java 1.5. То, что вы перечисляете первым, - это старый способ, второй-новый способ.

С помощью HashMap вы можете делать такие вещи, как:

HashMap<String, Doohickey> ourMap = new HashMap<String, Doohickey>();

....

Doohickey result = ourMap.get("bob");

Если бы у вас не было типов на карте, вам пришлось бы сделать это:

Doohickey result = (Doohickey) ourMap.get("bob");

Это действительно очень полезно. Это поможет вам поймать ошибки и избежать написания всевозможных дополнительных бросков. Это была одна из моих любимых особенностей 1.5 (и выше).

вы все еще можете поместить несколько вещей на карте, просто укажите его как Map, затем вы можете поместить любой объект (строку, другую карту и целое число, а также три MyObjects, если вы так склонны).

Eclipse рекомендует объявить тип HashMap, потому что это обеспечивает некоторую безопасность типов. Конечно, это звучит так, как будто вы пытаетесь избежать безопасности типа из своей второй части.

Если вы хотите сделать последнее, попробуйте объявить map как HashMap<String,Object>.

то, как вы пишете это эквивалентно

HashMap<Object, Object> map = new HashMap<Object, Object>();

то, что находится внутри скобок, вы сообщаете компилятору, что вы собираетесь поместить в HashMap, чтобы он мог выполнить проверку ошибок для вас. Если объект, объект - это то, что вы на самом деле хотите (возможно, нет), вы должны явно объявить его. В общем случае вы должны быть настолько явными, насколько это возможно с объявлением, чтобы облегчить проверку ошибок компилятором. То, что вы описали, вероятно, должно быть объявлено как это:

HashMap<String, Object> map = new HashMap<String, Object>();

второй использует дженерики, которые пришли с Java 1.5. Это уменьшит количество приведений в коде и может помочь вам поймать ошибки в compiletime вместо времени выполнения. Тем не менее, это зависит от того, что вы кодируете. Быстрая и грязная карта для хранения нескольких объектов различных типов не нуждается в дженериках. Но если карта содержит объекты, все спускающиеся от типа, отличного от объекта, это может стоить того.

предыдущий плакат неверен относительно массива на карте. Массив на самом деле объект, так что это допустимое значение.

Map<String,Object> map = new HashMap<String,Object>();
map.put("one",1); // autoboxed to an object
map.put("two", new int[]{1,2} ); // array of ints is an object
map.put("three","hello"); // string is an object

кроме того, поскольку HashMap является объектом, он также может быть значением в HashMap.

HashMap может содержать любой объект в качестве значения, даже если это другой HashMap. Eclipse предлагает объявить типы, потому что это рекомендуемая практика для коллекций. под Java 5. Вы можете игнорировать предложения Eclipse.

в Java 5 int (или любой примитивный тип) будет autoboxed в целое число (или другой соответствующий тип) при добавлении его в коллекцию. Будьте осторожны с этим, хотя, как есть некоторые уловы для использования автобоксинг.

затмение предлагает вам определить generic type Так что вы можете иметь type safety. Вы можете написать

Map m = new HashMap();

который не обеспечивает безопасность типа, но следующий обеспечит безопасность типа

Map<Object,Object> = new HashMap<Object,Object>();

The Object может быть любого типа, такие как String,Integer etc.

в ответ на ваш второй вопрос: Да HashMap может содержать различные типы объектов. Является ли это хорошей идеей или нет, зависит от проблемы, которую вы пытаетесь решить.

тем не менее, ваш пример не будет работать. Значение int не является объектом. Вы должны использовать класс-оболочку Integer для хранения значения int в HashMap