Różnice przy tworzeniu obiektu klasy HashMap

0

Siemka.
Moglibyście mi wyjaśnić różnicę między tym:

private Map<Integer, String>locations = new HashMap<Integer, Location>();

a tym:

private HashMap<Integer, String> locations = new HashMap<Integer, Location>();

Co daje sposób pierwszy czego nie uzyskam za pomocą drugiego sposobu?

0

Sorka, powinno być:

private Map<Integer, Location> locations = new HashMap<Integer, Location>();

i

private HashMap<Integer, Location> locations = new HashMap<Integer, Location>();
0

Pierwsze tworzenie obiektu jest polimorficzne, bo "wskaźnikiem/referencją" jest interfejs Map, drugie natomiast tworzy obiekt, do którego "wskaźnik/referencja" jest tego samego typu co gotowy obiekt:

https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html

Innymi słowy HashMap implementuje Map.

0

Dzięki za odpowiedź.
Rozumiem mniej więcej co się dzieje, tylko że nie bardzo pojmuję "zalety i wady" korzystania np. z pierwszego sposobu zamiast drugiego.

0

Żeby poznać zalety pierwszego sposobu musisz bliżej poznać zalety interfejsów i w ogóle popracować trochę z interfejsami oraz poczytać o polimorfizmie.

1

Pierwszy sposób mówi że pole jest "jakąś mapą". Możesz podmienić kiedyś tą mapę na inną, a cała reszta kodu nie ulegnie zmianie. Jeśli wpiszesz tam konkretnie HashMap, to zmiana na TreeMap będzie wymagała poprawek w połowie kodu.

0

Dla mnie różnica dotyczy dostępnych metod np. List nie ma wszystkich metod ArrayList.

1
ronaldexim napisał(a):

Dla mnie różnica dotyczy dostępnych metod np. List nie ma wszystkich metod ArrayList.

I to jest najlepsze podsumowanie. Jeśli użyjesz metod z ArrayList lub HashMap, ktôrych nie na w List lub Map to przestawienie się na LinkedList czy np. ConcurrenyNavigableHashMap może wymagać więcej zmian w kodzie. Trzymanie się interfejsu przed tym zabezpiecza.

Generalnie warto używać interfejsu w publicznym Api. Kiedy my przyjmujemy jako parametr mapę to lepiej żeby to była Map niż HasMap. Tak samo jak zwracamy lepiej Map niż klasę konkretną. Inaczej może się okazać, że np. przy zmianie z HasMap na ConcurrentNav..Map (wielowątkowa) mysimy poprosić wszystkich korzystających z naszej metody o zmiany w kodzie, albo będziemy musieli wrappować wyniki do HashMapy....

Przy polach prywatnych ( jak w przykładzie) problemu raczej nie ma, bo w razie czego zmian będzie mało i będą w jednym pliku. Robimy to Map raczej z przyzwyczajenia niž dla większego sensu.
Jeszcze mniejszy zysk ma trzymanie się interfejsów w zmiennych lokalnych. Nie szkodzi, ale i niewiele daje. (Pomijam ludzi kodujących metody na ponad 30 linii).

(Gwizadka1) Są też, dość rzadkie, przypadki,, kiedy to publiczne Api powinno pokazywać implementację, a nie generyczny interfejs, ale to raz na 5 lat sie zdarza.
(gwiazdka2) zasada korzystania z interfejsów jest ogólna i nie dotyczy tylko List i Map. To jest samo sedno istnienia interfejsów. Po to je robimy.

1

Jeśli to Java 7+ to powinno być:

 private Map<Integer, Location> locations = new HashMap<>();
 // lub
 private HashMap<Integer, Location> locations = new HashMap<>();

https://www.javaworld.com/article/2074080/core-java/jdk-7--the-diamond-operator.html

0

Dzięki :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1