У меня вопрос по поводу HashMap<Key,Values>
.
Давайте представим себе такой сценарий:
У меня есть класс Person:
Person a=new Person(int id, String fullName, int age)
Я не определял equals
и hashCode
в этом классе.
Предположим, я хочу сохранить 10 Person
в HashMap
, определенном как:
Map<Integer,Person> hashMap=new HashMap<Integer,Person>();
Итак, я беру количество людей из базы данных, а затем делаю цикл for:
String name = "test"; int age = "20";
for(int i=size;i<size+10;i++)
{
hashMap.put(Integer.valuesOf(i), new Person(i,name+"i",age++));
}
Я думаю, что hashMap будет использовать hashCode()
класса Integer, и я получу уникальный хеш, который будет храниться в hashMap вместе с объектами Person
.
Если я уверен, что этот хеш будет уникальным, мне не нужно определять hashCode
и equals
на объекте, не так ли? или, по крайней мере, мне нужно просто определить равные, чтобы сравнивать двух человек в будущем.
Я ошибаюсь?
Для ключей в HashMap
вам нужен equals()
(и метод hashCode()
соответствует equals()
- это означает, что для двух ключей a
и b
, если a.equals(b)
истинно, то они должны иметь один и тот же хеш-код, но если a.equals(b)
их хеш-коды должны быть разными). Для значений таких требований относительно equals()
и hashCode()
не существует.
Ключ HashMap
должен соответствовать hashCode
и equals
. Обратите внимание, что hashCode
не обязательно должен быть уникальным, но чем ближе он к нему, тем выше производительность. java.lang.Integer
уже реализует и то, и другое.
Значение HashMap
не обязательно должно что-либо реализовывать, хотя наличие метода equals
поможет, если вы хотите использовать containsValue.
Спасибо за ваш ответ, так что в реальной программе мне следует создать еще один класс для управления ключами только класса Person, не так ли?
@elmoutawakil прямо сейчас, Person
— твоя ценность. Это может быть разумным ключом, если вы хотите сопоставить человека с некоторыми связанными с ним данными (например, Map<Person, List<Pet>>
), но на самом деле все зависит от потребностей ваших программ. Конечно, если вы решите использовать Person
в качестве ключа, вам нужно будет убедиться, что вы реализовали equals
и hashCode
для него.
Большое спасибо, сэр, за ваш ответ, пожалуйста, последний: когда я сохраняю ключ и значения <Person,Person> , насколько я понимаю, я сохраняю ссылку в ведре хэш-карты, чтобы не было неиспользованной памяти? Я говорю это потому, что для ключа важны только hashCode() и Equals().
@elmoutawakil извини, я не понимаю этот вопрос. Можете ли вы уточнить?
ах, извините, я хотел просто сказать, что hashMap хранит ссылки на объекты, поэтому добавление Person в качестве значения, а также в качестве ключа (двойное воздействие) не приведет к увеличению использования памяти, не так ли?
Вместо хранения Map<Person,Person> вам следует использовать Set<Person>.
@elmoutawakil Это не будет дублировать пространство (думайте об этом как о двух ссылках на один и тот же объект, но, как сказал JustanotherJavaprogrammer, если вы сопоставляете Person
с одним и тем же экземпляром Person
, это просто очень неуклюжий способ иметь а Set
.
Начиная с
Integer
,equals
иhashcode
основаны исключительно на значенииint
, так что не беспокойтесь. Возвращаемое значениеhashcode
— это даже само значениеint
для классаInteger
.