2

I used a HashMap for my program and it works fine, but I don't understand the difference between these initializations of HashMap.

Let's say I'm implementing a HashMap with a character as a key and an integer as a value. What's the difference between these?

HashMap<Character, Integer> alphabet1 = new HashMap();
HashMap<Character, Integer> alphabet1 = new HashMap<Character, Integer>();
HashMap alphabet1 = new HashMap<Character, Integer>();
Map alphabet1 = new HashMap<Character, Integer>();
HashMap alphabet1 = new HashMap<Character, Integer>();
HashMap alphabet1 = new HashMap();
Map alphabet1 = new HashMap();
Radiodef
  • 37,180
  • 14
  • 90
  • 125
user1742646
  • 303
  • 3
  • 9
  • 3
    Get through from generics http://docs.oracle.com/javase/tutorial/java/generics/ you will automatically get understand all these. – Vikas Verma Oct 25 '14 at 18:14
  • All those choices, and it still doesn't include the one that I'd typically use: `Map alphabet1 = new HashMap();`. [I'm still using Java 5] – splungebob Oct 25 '14 at 18:18
  • And as of Java 7 (see http://docs.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html) you can write: `Map alphabet1 = new HashMap<>();` – splungebob Oct 25 '14 at 18:21

3 Answers3

9

Anything involving HashMap or Map without a type argument (the angle brackets < and > and the part between them) is a raw type and shouldn't be used. A raw type is not generic and lets you do unsafe things.

The "correct" ways are

Map<Character, Integer> alphabet1 = new HashMap<Character, Integer>();
HashMap<Character, Integer> alphabet1 = new HashMap<Character, Integer>();

The first uses the interface Map as the reference type. It is generally more idiomatic and a good style.

Also another way you did not mention, using the Java 7 diamond operator

Map<Character, Integer> alphabet1 = new HashMap<>();
HashMap<Character, Integer> alphabet1 = new HashMap<>();

Which is more or less equivalent to the first two correct ways. The arguments to the reference type on the left-hand side are supplied implicitly to the constructor on the right-hand side.

Community
  • 1
  • 1
Radiodef
  • 37,180
  • 14
  • 90
  • 125
3

You missed the right choice:

Map<Character, Integer> alphabet1 = new HashMap<Character, Integer>();
  1. Generics declaration allows compiler to check your 'alphabet1' usages during compile-time.
  2. Map/HashMap on left side declares how your 'alphabet1' variable should be considered: either as Map (interface) or HashMap (instance of concrete class). Of course interface is preferred - it makes your code more robust to further changes.
ursa
  • 4,404
  • 1
  • 24
  • 38
1
HashMap<Character, Integer> alphabet1 = new HashMap(); // (1)

(1) initializes a HashMap without using generics but uses an unsafe cast to a HashMap with generics afterwards. This should raise a compiler warning.

HashMap<Character, Integer> alphabet1 = new HashMap<Character, Integer>(); // (2)

(2) Initializes a HashMap with generics and declares a variable of the type HashMap with generics. It can be shorthanded to

HashMap<Character, Integer> alphabet1 = new HashMap<>(); // (2b)

Here, the compiler uses type inference to infer the genrics of the HashMap from the declaration of the left hand side.

HashMap alphabet1 = new HashMap<Character, Integer>(); // (3)

(3) Initialzes a HashMap with generics, but the variable alphabet1 does not reuse the generics information. Thus, you can not access the methods on this HashMap value in a generic manner (e.g., you will get a value cast to an java.lang.Object when calling alphabet1.get('a') and not cast to an Integer).

Map alphabet1 = new HashMap<Character, Integer>(); // (4)

(4) is similar to (3) but here, the alphabet1 is typed with Map instead of HashMap. Thus, you cannot access methods being defined in HashMap but not in its super interface Map.

HashMap alphabet1 = new HashMap(); // (5)

(5) is similar to (3), it does not use generics for initializing the HashMap.

Map alphabet1 = new HashMap(); // (6)

(6) is similar to (4) and does not use generics for initializing the HashMap.

Claas Wilke
  • 1,951
  • 1
  • 18
  • 29