What's the difference between these ways of initializing a HashMap?

前端 未结 3 1935
夕颜
夕颜 2020-12-10 21:38

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 Ha

相关标签:
3条回答
  • 2020-12-10 22:15

    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.

    0 讨论(0)
  • 2020-12-10 22:17
    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.

    0 讨论(0)
  • 2020-12-10 22:24

    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.
    0 讨论(0)
提交回复
热议问题