当只有 equals 被覆盖时,为什么 list 发现 item 为 true?
When only equals is override, why list finds item as true?
我知道 hashcode 和 equals 都需要被覆盖。我尝试了下面的程序,想知道为什么列表能够搜索学生,而当只覆盖 equals 时,set 无法搜索学生:
import java.util.*;
class Student {
private int id;
private String name;
public Student(int id, String name) {
this.name = name;
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof Student))
return false;
if (obj == this)
return true;
return this.getId() == ((Student) obj).getId();
}
}
public class StudentHashcodeEquals {
public static void main(String[] args) {
Student alex1 = new Student(1, "Alex");
Student alex2 = new Student(1, "Alex");
System.out.println("alex1 hashcode = " + alex1.hashCode());
System.out.println("alex2 hashcode = " + alex2.hashCode());
System.out.println("Checking equality between alex1 and alex2 = " + alex1.equals(alex2));
List<Student> studentsLst = new ArrayList <Student>();
studentsLst.add(alex1);
studentsLst.add(alex2);
System.out.println("Arraylist size = " + studentsLst.size());
System.out.println("Arraylist contains Alex = " + studentsLst.contains(new Student(1, "Alex")));
HashSet <Student> students = new HashSet <Student>();
students.add(alex1);
students.add(alex2);
System.out.println("HashSet size = " + students.size());
System.out.println("HashSet contains Alex = " + students.contains(new Student(1, "Alex")));
}
}
/*
alex1 hashcode = 366712642
alex2 hashcode = 1829164700
Checking equality between alex1 and alex2 = true
Arraylist size = 2
Arraylist contains Alex = true
HashSet size = 2
HashSet contains Alex = false
*/
当学生被插入到列表中时,我假设它会将它插入到 2 个不同的桶中,因为哈希码实现不存在并且默认对象哈希码将被启动并将它们存储到 2 个不同的哈希中代码和搜索另一个对象时,它必须首先通过哈希码定位桶,但没有哈希码实现,那么list如何仍然能够识别它而set却不能??
谢谢!
列表不使用对象的哈希码。根据它们的类型,它们存储对象的引用数组。
如果您在列表上调用 contains
,它将使用 .equals()
遍历列表以检查对象是否在列表中。
我知道 hashcode 和 equals 都需要被覆盖。我尝试了下面的程序,想知道为什么列表能够搜索学生,而当只覆盖 equals 时,set 无法搜索学生:
import java.util.*;
class Student {
private int id;
private String name;
public Student(int id, String name) {
this.name = name;
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof Student))
return false;
if (obj == this)
return true;
return this.getId() == ((Student) obj).getId();
}
}
public class StudentHashcodeEquals {
public static void main(String[] args) {
Student alex1 = new Student(1, "Alex");
Student alex2 = new Student(1, "Alex");
System.out.println("alex1 hashcode = " + alex1.hashCode());
System.out.println("alex2 hashcode = " + alex2.hashCode());
System.out.println("Checking equality between alex1 and alex2 = " + alex1.equals(alex2));
List<Student> studentsLst = new ArrayList <Student>();
studentsLst.add(alex1);
studentsLst.add(alex2);
System.out.println("Arraylist size = " + studentsLst.size());
System.out.println("Arraylist contains Alex = " + studentsLst.contains(new Student(1, "Alex")));
HashSet <Student> students = new HashSet <Student>();
students.add(alex1);
students.add(alex2);
System.out.println("HashSet size = " + students.size());
System.out.println("HashSet contains Alex = " + students.contains(new Student(1, "Alex")));
}
}
/*
alex1 hashcode = 366712642
alex2 hashcode = 1829164700
Checking equality between alex1 and alex2 = true
Arraylist size = 2
Arraylist contains Alex = true
HashSet size = 2
HashSet contains Alex = false
*/
当学生被插入到列表中时,我假设它会将它插入到 2 个不同的桶中,因为哈希码实现不存在并且默认对象哈希码将被启动并将它们存储到 2 个不同的哈希中代码和搜索另一个对象时,它必须首先通过哈希码定位桶,但没有哈希码实现,那么list如何仍然能够识别它而set却不能??
谢谢!
列表不使用对象的哈希码。根据它们的类型,它们存储对象的引用数组。
如果您在列表上调用 contains
,它将使用 .equals()
遍历列表以检查对象是否在列表中。