В чем отличие объявление переменных HashMap от Map?

В чем отличие если мы объявим переменную так:

HashMap<Type, Type> lala = new HashMap<>();

Или так:

Map<Type, Type> lala = new HashMap<>();

В чем практическое отличие, почему в некоторых случаях объявляют как в первом случае, а в других как во втором. Так же касается и ArrayList


Ответы (2 шт):

Автор решения: Nowhere Man

Отличие в том, что во втором случае lala объявляется как ссылка на интерфейс Map, а в первом -- на конкретную реализацию HashMap этого интерфейса. Соответственно, во втором случае можно легко переприсвоить переменной lala какую-нибудь другую реализацию:

Map<String, Integer> lala = new HashMap<>();
lala = new TreeMap<>(lala); // получить отсортированную мапу

Особой разницы в данном случае между двумя указанными способами нет, так как HashMap не имеет каких-то своих особых методов, не объявленных в интерфейсе, в отличие от реализации TreeMap (для которой, впрочем существуют расширенные интерфейсы SortedMap / NavigableMap).

Первый способ позволяет воспользоваться полным функционалом, реализованным в классе, без дополнительного приведения типа.

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


То же относится и к связке List / ArrayList. Например, если нужно пользоваться методами доступа к элементам списка по индексу get(int index) / set(int index, E elem), то придётся использовать конкретную реализацию:

ArrayList<Foo> arrList = new ArrayList<>();
arrList.add(new Foo(1));
arrList.set(0, new Foo(2));

Но в основном, при создании списков другими способами: Arrays.asList, List.of, и др. гораздо удобнее пользоваться общим интерфейсом, не вдаваясь в детали реализации:

List<Integer> nums = Arrays.asList(1, 2, 3); // java.util.Arrays$ArrayList
List<Integer> copies = Collections.nCopies(5, 10); // java.util.Collections$CopiesList
List<String> strs = List.of("a", "b"); // java.util.ImmutableCollections$List12
→ Ссылка
Автор решения: стасевич

тут надо понимание интерфейсов и коллекций. если в двух словах Map, как и List интерфейсы, которые реализуют коллекции типа HashMap и ArrayList и т.д. а также реализуют все методы интерфейса.
Проще обращаться именно к интерфейсу, или так скажем, к более общему объекту/классу/сущности, нежели к ее конкретной реализации

public void someMethod(List<String> list)  {
} 

В этот метод можем передавать ArrayList, LinkedList и любую другую коллекцию, реализующую List.

так же переприсвоить другую реализацию ссылки

List<Integer> list = new LinkedList<>();

              list = new ArrayList<>();  

по этому принципу работает ключевое слово var

var list = new ArrayList<>();
→ Ссылка