Set中存储的元素不重复,add()方法返回布尔值,遇到重复元素返回false;
Set中允许添加null;
Set不保证元素的顺序;
HashSet
***遍历HashSet:迭代器/增强for循环
***HashSet去重复的原理:
/*自定义Person类*/
public class Person{
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
//向集合中添加属性相同的重复对象
public static void main(String[] args) {
// demo1();
HashSet<Person> hs=new HashSet<>();
hs.add(new Person("zhangsan",23));
hs.add(new Person("zhangsan",23));
hs.add(new Person("zhangsan",23));
hs.add(new Person("lisi",24));
hs.add(new Person("lisi",24));
hs.add(new Person("lisi",24));
System.out.println(hs);
}
打印结果:
[Person [name=zhangsan, age=23], Person [name=lisi, age=24], Person [name=lisi, age=24], Person [name=zhangsan, age=23], Person [name=zhangsan, age=23], Person [name=lisi, age=24]]
new一次创建一个新对象,地址是不同的,那么如何保证对象的唯一性呢?
测试1:类中重写equals()方法,属性相同就返回true
@Override
public boolean equals(Object obj) {
Person p=(Person)obj;
return this.name.equals(p.name)&&this.age==p.age;
}
结果同上,说明这个方法并没有生效。
测试2:重写hashCode()方法
@Override
public int hashCode() {
return 10;//所有对象的hash值相同
}
结果同上,说明未生效
测试3:重写equals()和hashCode()方法
[Person [name=zhangsan, age=23], Person [name=lisi, age=24]]
结果中不含有重复对象
说明当重写了hashCode()方法后,equals()生效了。
当调用add(obj)添加元素时,首先比较obj的hashcode值,如果一样就调用equals方法比较,返回true则添加失败。因此,obj类中需要重写hashCode和equals方法。hashCode()和equals()方法可以使用eclipse自动生成。
底层实际是由HashMap实现的。当向HashSet中添加元素的时候,首先计算元素的hashcode值,然后用这个(元素的hashcode)%(HashMap集合的大小)+1计算出这个元素的存储位置,如果这个位置位空,就将元素添加进去;如果不为空,则用equals方法比较元素是否相等,相等就不添加,否则找一个空位添加。
参考:
***HashSet扩容机制:
默认初始容量为16,加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容。扩容增量:原容量的 1 倍;如 HashSet的容量为16,一次扩容后是容量为32。