一、概述
Collection下面有两个子接口:
List: ArrayList LinkedList Vector 可重复的,有序的
Set: HashSet 底层是一个hash表 存储效率相当高
TreeSet底层是一个树状结构 要求保存的数据必须是有比较顺序的。自然顺序。
Set接口下面没有独特的方法,完全可以使用Collection下面的方法
二、示例(重写hashCode和equals):
import java.util.HashSet;
import java.util.Set;
/**
* @author xue_yun_xiang
* @create 2021-03-16-20:39
*/
class Cat {
int age;
String name;
public Cat() {
}
public Cat(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Cat{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public int hashCode() {
return age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
Cat c = (Cat)obj;
return this.age == c.age && this.name.equals(c.name);
}
}
public class Demo4 {
public static void main(String[] args) {
HashSet<Cat> list = new HashSet<>();
Cat c1 = new Cat(1, "狸花猫");
Cat c2 = new Cat(1, "狸花猫");
list.add(c1);
list.add(c2);
//重写方法之前:
//System.out.println(list);//[Cat{age=1, name='狸花猫'}, Cat{age=1, name='狸花猫'}]
//System.out.println(c1.hashCode());//460141958
//System.out.println(c2.hashCode());//1163157884
//此时两个内容完全一样的两个对象都存进了HashSet,给人的表象是可以存入重复的数据,这样是不合理的
//只重写hashCode()
//System.out.println(list);//[Cat{age=1, name='狸花猫'}, Cat{age=1, name='狸花猫'}]
//System.out.println(c1.hashCode());//1
//System.out.println(c2.hashCode());//1
//此时,虽然把表象的hash改为相等的,但仍执行Object类的equals方法,而此方法是严格的,
// 会比较物理地址,而p1,p2是两个不同的物理地址,所以还会可以把p1,p2存入HashSet
//只重写equals()
//System.out.println(list);//[Cat{age=1, name='狸花猫'}, Cat{age=1, name='狸花猫'}]
//System.out.println(c1.hashCode());//460141958
// System.out.println(c2.hashCode());//1163157884
//此时,虽然重写了equals,改成了只比较内容,但hash值不同,就不再执行equals方法
//同时重写hashCode() 和 equals()
System.out.println(list);//[Cat{age=1, name='狸花猫'}]
System.out.println(c1.hashCode());//1
System.out.println(c2.hashCode());//1
//此时才符合HashSet数据不能重复的特性
}
}