Set集合的主要特点
无序性: Set集合中的元素是无序的,与List不同,Set不保证元素的存储顺序。
不允许重复: Set集合不允许包含重复的元素。如果你尝试添加一个重复元素,Set会忽略它。
Set集合不仅仅是不允许同一个对象重复存储,不同的对象内容相同的情况也不能重复存储。这是通过hashCode()和equals()方法来实现的。
hashCode()方法:
当我们向Set中添加元素时,首先会调用该对象的hashCode()方法,计算并返回一个整数(哈希值)。比较为了提高比较效率,我们需要先进行hash计算。如果两个对象的hash值不同,则表示当前是两个对象,但是如果两个对象的hash值是相同的,则这两个对象可能相同,此时在进行equals。
equals()方法:
如果两个对象的哈希值相同,Set会进一步调用equals()方法,来确定这两个对象是否真正相同。只有当equals()方法返回false时,才将新对象添加到集合中。
这是一个实例:
import java.util.HashSet;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
Set set = new HashSet();
Student s1 = new Student('A',20,1001);
Student s2 = new Student('A',20,1001);
Student s3 = new Student('B',18,1005);
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set);
}
}
class Student{
char name;
int age;
int no;
public Student(char name, int age, int no) {
this.name = name;
this.age = age;
this.no = no;
}
@Override
public String toString() {
return "Student{" +
"name=" + name +
", age=" + age +
", no=" + no +
'}';
}
@Override
public int hashCode() {
return name*2+age*2+no*8;
}
//为了让Set集合正常工作我们需要重写equals的同时重写hashCode方法
@Override
public boolean equals(Object o) {
if (this == o){
return true;
}
if (o instanceof Student){
Student s = (Student) o;
if (this.name==s.name&&this.age==s.age&&this.no==s.no){
return true;
}
return false;
}
return false;
}
}
在这个示例中,我们先定义了一个Student类,并且重写了hashCode()和equals()方法。Set会先通过hashCode()方法判断对象的哈希值,如果哈希值相同,再通过equals()方法判断两个对象是否相同。
hashCode()方法: 计算学生对象的哈希值,通过name、age和no属性进行简单的计算。
equals()方法: 先检查当前对象(this)和传入的对象(o)是否是同一个对象引用。如果this和o指向同一个内存地址,那么它们必然相等。再检查传入的对象o是否是Student类的实例。最后对Student对象的三个属性name、age和no进行逐一比较。