HashSet的使用
HashSet是Set接口的实现类
特点:无序,无下标,不能重复的
他是通过哈希表结构存储的,哈希表结构其实就是数组+链表+红黑树(JDK1.8之后)的结合
HashSet存储元素的过程:
他是如何判断所添加的元素是否重复呢,依据是什么?
-
根据hashcode的值来计算保存的位置,如果此位置为空,则直接保存,如果不为空,执行第二步
2.再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
因为HashSet要通过hashcode()与equals()方法来判断添加的元素是否重复,所以如果你想通过属性值是否相同来判断是否是同一个元素,就需要重写hashcode()与equals()方法,修改判断规则
Student类(重写equals()与hashcode())
public class Student {
private String name;
private int age;
public Student() {
}
public Student(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
protected void finalize() throws Throwable {
System.out.println(name+"被回收");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return age == student.age &&
name.equals(student.name);
}
}
HaseSet的使用
/**
* HashSet的使用
* 存储结构:哈希表(数组+链表+红黑树)
* 存储过程(重复依据):
* (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空,执行第二步
* (2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
*/
public class Test {
public static void main(String[] args) {
//创建集合
HashSet<Student> hashSet = new HashSet<>();
Student s1 = new Student("学生一", 23);
Student s2 = new Student("学生二", 28);
Student s3 = new Student("学生三", 63);
Student s4 = new Student("学生四", 53);
//1添加元素
hashSet.add(s1);
hashSet.add(s2);
hashSet.add(s3);
hashSet.add(s4);
System.out.println("学生人数:"+hashSet.size());//4
System.out.println(hashSet.toString());
hashSet.add(new Student("学生一", 23));
//首先重写hashcode,此时还是添加成功,因为equals也要作比较,重写equals后因为添加的属性值与集合中的相同,返回ture,所以添加失败
System.out.println(hashSet.size());//4
System.out.println(hashSet.toString());
//2删除元素
//hashSet.remove(s1);
//hashSet.remove(new Student("学生一", 23));
//也能删除成功,重写了hashcode()与equals()后先根据hashcode找,再比较equals,返回true,则删除成功
System.out.println("删除后剩余人数:"+hashSet.size());//3
//3遍历【重点】
//3.1使用增强for
System.out.println("==============增强for=================");
for(Student student:hashSet){
System.out.println(student);
}
//3.2迭代器
System.out.println("==============迭代器=================");
Iterator<Student> iterator = hashSet.iterator();
while (iterator.hasNext()){
Student next = iterator.next();
System.out.println(next);
}
//4判断
System.out.println(hashSet.contains(s1));//true
System.out.println(hashSet.contains(new Student("学生一", 23)));//true
//重写了hascode()与equals()所以返回true
System.out.println(hashSet.isEmpty());//false
}
}