Подтвердить что ты не робот

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

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

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

    HashMap x = new HashMap();
    

    Но Eclipse продолжает предполагать, что я использую:

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

    Что лучше?

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

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

    В первом put() я хочу, чтобы int как значение, во втором a int[] и третья строка. Это нормально делать на Java с помощью HashMap s? Кроме того, хорошо ли хранить HashMap как значение в пределах HashMap?

4b9b3361

Ответ 1

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

 Map x = new HashMap();

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

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

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

В Java 7 и более поздних версиях вы можете сделать

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

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

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

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

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

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

Ответ 2

Это изменение, сделанное с помощью 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 (и новее).

Вы можете поместить на карте несколько вещей, просто укажите их как "Карта", тогда вы можете поместить любой объект в (String, другую Map и Integer и три MyObjects, если вы так наклонены).

Ответ 3

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

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

Ответ 4

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

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

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

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

Таким образом, вы хотя бы заявляете, что ваши ключи будут строками, но ваши ценности могут быть любыми. Просто не забудьте использовать бросок, когда вы получите значение обратно.

Ответ 5

Второй использует дженерики, входящие в 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.

Ответ 6

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

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

Ответ 7

Eclipse предлагает вам определить generic type, чтобы вы могли иметь type safety. Вы можете написать

Map m = new HashMap();

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

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

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

Ответ 8

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

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

Ответ 9

Map.of литералы

Начиная с Java 9, существует еще один способ создания экземпляра Map. Вы можете создать неизменяемую карту из нуля, одной или нескольких пар объектов в одной строке кода. Это очень удобно во многих ситуациях.

Для пустого Map, который нельзя изменить, позвоните Map.of(). Зачем вам нужен пустой набор, который нельзя изменить? Один из распространенных случаев - избегать возврата значения NULL, если у вас нет действительного контента.

Для одной пары ключ-значение вызовите Map.of( myKey , myValue ). Например, Map.of( "favorite_color" , "purple" ).

Для нескольких пар ключ-значение используйте серию пар ключ-значение. '' Map.of("favour_foreground_color", "purple", "favour_background_color", "cream") '.

Если эти пары трудно читать, вы можете использовать Map.of и передавать Map.Entry объекты.

Обратите внимание, что мы получаем объект интерфейса Map. Мы не знаем базовый конкретный класс, используемый для создания нашего объекта. Действительно, команда Java может использовать разные конкретные классы для разных данных или изменять класс в будущих выпусках Java.

Правила, обсуждаемые в других Ответах, все еще применяются здесь в отношении безопасности типов. Вы объявляете ваши предполагаемые типы, и ваши переданные объекты должны соответствовать. Если вы хотите значения различных типов, используйте Object.

Map< String , Color > preferences = Map.of( "favorite_color" , Color.BLUE ) ;