The correct way to initialize a HashMap and can a HashMap use different types of values?

So, I have two questions about HashMap in Java:

  • What is the correct way to initialize a HashMap ? I think in my situation it would be better to use:

     HashMap x = new HashMap(); 

    But Eclipse continues to assume that I am using:

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

    What's better?

  • Can HashMap store values ​​of various types of objects / data types? For example, will this work and will be fine:

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

    In the first put() I want int as a value, in the second a int[] and the third line. Is it ok to do in Java using HashMap s? Also, is it good to store a HashMap as a value within a HashMap ?

+63
java hashmap standards
Aug 28 '09 at 16:01
source share
9 answers

It really depends on what type of security you need. Not a general way to do this is best done as:

  Map x = new HashMap(); 

Note that x is entered as a Map . this makes it much easier to change implementations (in TreeMap or LinkedHashMap ) in the future.

You can use generics to provide a certain level of type safety:

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

In Java 7 and later, you can do

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

The above, although more verbose, avoids compiler warnings. In this case, the contents of the HashMap can be any Object , so there can be Integer , int[] , etc. What are you doing.

If you are still using Java 6, Guava Libraries (although this is fairly easy to do yourself) has a newHashMap() method, which avoids duplication of general type information when new executed. It infers the type from the variable declaration (this is a Java function not available to designers before Java 7).

By the way, when you add an int or other primitive, Java does this automatically. This means the code is equivalent to:

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

You can put the HashMap as a value in another HashMap , but I think there are problems if you do it recursively (this puts the HashMap as a value in itself).

+101
Aug 28 '09 at 16:12
source share

This is a change made using Java 1.5. What you list first is the old way, second is the new one.

Using a HashMap, you can do things like:

 HashMap<String, Doohickey> ourMap = new HashMap<String, Doohickey>(); .... Doohickey result = ourMap.get("bob"); 

If you did not have types on the map, you will need to do this:

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

This is really very helpful. This helps you catch mistakes and avoid writing all kinds of additional videos. This was one of my favorite features of 1.5 (and newer).

You can put several things on the map, just specify them as "Map", then you can put any object in (String, another Map and Integer and three MyObjects, if you are so inclined).

+14
Aug 28 '09 at 16:09
source share

Eclipse recommends that you declare a HashMap type, as this provides security for a specific type. Of course, it looks like you are trying to avoid type safety from your second part.

If you want to do the latter, try declaring the map as a HashMap<String,Object> .

+4
Aug 28 '09 at 16:05
source share

The way you write it is equivalent

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

With parentheses, you tell the compiler what you intend to put in the HashMap so that it can perform error checking for you. If Object, Object is what you really want (maybe not), you should explicitly declare it. In general, you should be as clear as you can with the declaration to facilitate compiler error checking. You have probably described the following:

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

Thus, you at least declare that your keys will be strings, but your values ​​can be any. Just remember to use the throw when you get the value back.

+3
Aug 28 '09 at 16:21
source share

The second uses the generics included with Java 1.5. This will reduce the number of throws in your code and help you catch errors in compiletime instead of runtime. However, it depends on what you code. A quick and dirty card for storing several objects of different types does not need generics. But if objects that drop from another type of object are stored on the map, it may be worth it.

The previous poster is incorrect regarding the array on the map. An array is actually an object, so it is a valid value.

 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 

Also, since the HashMap is an object, it can also be a value in the HashMap.

+2
Aug 28 '09 at 16:27
source share

A HashMap can contain any object as a value, even if it is another HashMap. Eclipse invites you to declare types because it is the recommended practice for collections. under Java 5. You can ignore Eclipse suggestions.

In Java 5, an int (or any primitive type) will be autoboxed into an Integer (or other appropriate type) when it is added to the collection. Be careful with this, although there are some tricks to using autoboxing.

+1
Aug 28 '09 at 16:08
source share

Eclipse suggests you define a generic type so that you can have type safety . You can write

 Map m = new HashMap(); 

which does not guarantee type safety, but the subsequent will ensure type safety

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

Object can be any type, such as String , Integer , etc.

+1
Sep 09 '16 at 4:30
source share

In answer to your second question: Yes, a HashMap can contain different types of objects. Whether it is a good idea or not depends on the problem you are trying to solve.

However, your example will not work. The int value is not an object. You must use the Integer wrapper class to store the int value in a HashMap

0
Aug 28 '09 at 16:14
source share

Map.of literals

Starting with Java 9, there is another way to create a Map instance. You can create an immutable map from zero, one or more pairs of objects in one line of code. It is very convenient in many situations.

For an empty Map that cannot be changed, call Map.of() . Why do you need an empty set that cannot be changed? One common case is to avoid returning NULL unless you have valid content.

For one key-value pair, call Map.of( myKey , myValue ) . For example, Map.of( "favorite_color" , "purple" ) .

For multiple key-value pairs, use a series of key-value pairs. '' Map.of ("favorite_foreground_color", "purple", "favorite_background_color", "cream") '.

If these pairs are hard to read, you can use Map.of and pass Map.Entry objects.

Notice that we get a Map interface object. We do not know the base concrete class used to create our object. Indeed, the Java team may use different specific classes for different data or change the class in future releases of Java.

The rules discussed in other Answers still apply here in relation to type safety. You declare your intended types, and your passed objects must match. If you want values ​​of various types, use Object .

 Map< String , Color > preferences = Map.of( "favorite_color" , Color.BLUE ) ; 
0
Sep 18 '19 at 23:31
source share



All Articles