Когда выполняется java.util.Set проверка дубликатов
У меня есть очень простой вопрос, когда java.util.Set проверяет, являются ли добавляемые объекты дублирующими?
Поскольку у меня есть класс модели, как показано ниже, который переопределяет как методы equals, так и hashcode
public class SampleModel implements Comparable {
private String name;
public SampleModel(String name) {
this.name = name;
}
// Setter and Getter omitted
@Override
public boolean equals(Object arg0) {
boolean eq = false;
if (arg0 instanceof SampleModel
&& this.name.equalsIgnoreCase(((SampleModel) arg0).name)) {
eq = true;
}
return eq;
}
@Override
public int compareTo(Object arg0) {
return this.name.compareTo(((SampleModel) arg0).name);
}
@Override
public int hashCode() {
return this.name.length();
}
}
Затем я использую объекты модели в HashSet.
SampleModel s1 = new SampleModel("Satya");
SampleModel s2 = new SampleModel("Katti");
Set<SampleModel> samSet = new HashSet<SampleModel>();
System.out.println(samSet.add(s1));
System.out.println(samSet.add(s2));
s2.setName("Satya");
System.out.println(s2.getName());
System.out.println(s1 + ", " + s2);
В соответствии с условием равенства объекты одинаковы и равны, но HashSet будет содержать дубликаты.
Существует ли какое-либо нарушение w.r.t равно или hashcode?
Если этот код в порядке, то какие-либо способы предотвратить дублирование?
Я предполагаю, что любые поля, используемые при определении равных и hashcode, должны быть неумолимыми?
Ответы
Ответ 1
Я предполагаю, что любые поля, используемые при определении равных и hashcode, должны быть неизменными?
Это правильно.
Более точно, код в вашем вопросе нарушает следующую часть договора Set
:
Примечание. Следует проявлять большую осторожность, если изменяемые объекты используются в качестве заданных элементов. Поведение набора не указывается, если значение объекта изменяется таким образом, который влияет на равные сравнения, когда объект является элементом в наборе. Частным случаем этого запрета является то, что недопустимо, чтобы набор содержал себя как элемент.
Как только вы нарушите контракт, все ставки будут отключены.
Ответ 2
Пример для понимания:
import java.util.*;
public class Vector1{
public static void main(String args[]){
Set v=new HashSet();
Student st=new Student("12","naushad");
Student st1=new Student("12","naushad");
v.add(st1);
v.add(st);
System.out.println(st.hashCode());
st.sname="shouzia";
System.out.println(st.hashCode());
v.add(st);
v.add(st);
v.add("naushad");
v.add("naushad");
v.add("naushad");
System.out.println(v);
}
}
class Student{
public String sid;
public String sname;
Student(String sid,String sname){
this.sid=sid;
this.sname=sname;
}
public String toString(){
return sid+"\t"+sname;
}
}
Я создаю экземпляр двух объектов с одинаковыми данными, и он будет сохранен в Set, потому что оба
содержит другой хэш-код, поэтому здесь нет необходимости сравнивать
equals().
если метод hashcode() возвращает один и тот же хэш-код, тогда он проверяет метод equals() с свойством объекта и проверяет его.
изменения в объекте или нет?. В результате он сохранит этот объект в наборе или не может.