Почему метод put
принимает на вход key
параметр типа K
:
public V put(K key, V value)
а метод get
принимает на вход key
параметр типа Object
?
public V get(Object key)
Я пробовала в своей упрощённой реализации HashMap
использовать методы
public V get(K key)
public V put(K key, V value)
и это работает, точно так же, как работает и
public V get(Object key)
public V put(Object key, Object value)
Насколько я понимаю, метод put
должен принимать именно K key
и V value
, потому что в теле этого метода вызывается метод
void addEntry(int hash, K key, V value, int bucketIndex)
и без явного приведения типов (addEntry(hash, (K) key, (V) value, i);
) вызов этого метода вызвал бы ошибку компиляции, если бы key
и value
были бы типа Object
. Но почему метод get
принимает на вход key
параметр типа Object
, а не K
? Ведь это же как-то некрасиво, что ли (разный стиль)... и в этом должен быть, наверное, какой-то особый смысл.
Оргиниал ответа
Всё дело в том, что спецификация Map
не требует того, чтобы все ключи имели одинаковый тип. Она лишь требует корректного поведения метода equals
(и hashCode
для HashMap
) для объектов, которые используются в качестве ключей.
Конечно реализация метода equals
обычно требует, чтобы совпадали, в том числе, классы сравниваемых объектов. Но есть случаи, где имеется другое поведение. К примеру при сравнении реализаций java.util.List
(ArrayList
, LinkedList
и т.д.) требуется лишь, чтобы было эквивалентно именно содержимое этих списков. По указанной причине вы можете объявить переменную с типом Map<ArrayList, String>
при этом в метод get
передавать переменную типа LinkedList
и это будет вполне рабочий вариант.
Если же задаваться вопросом зачем объявлять Map<ArrayList, String>
вместо Map<List, String>
, то я могу привести, хоть и узконаправленный, но всё же пример. Представьте, что ваша переменная с типом Map<ArrayList, String>
периодически сериализуется, и вам очень важно быстродействие указанной сериализации. Поэтому вы требуете явно, чтобы записываемые ключи был именно указанного типа (я сейчас не буду говорить о реальной скорости сериализации ArrayList
). А при поиске объекта-значения в метод get
вы можете передавать аргумент любого типа, к примеру тот же LinkedList
, что немного упростит вам жизнь.
P.S. На эту тему можно конечно подискутировать, но таковы реалии Java. Вполне возможно, что это недостаток проектирования. И ссылаясь на этот ответ могу сказать, что пытались сделать нечто подобное, но возникли некоторые трудности, и от этой идеи отказались.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Задание - реализация алгоритма Крускала для вычисления минимальной суммарной длины дорожек в парке аттракционовЛимит времени - 5 секунд