首页 > 编程笔记 > Java笔记 阅读:10

Java HashSet类的用法(非常详细)

HashSet 是 Java Set 接口中的一个实现类。HashSet 类存储的元素是不可重复的,并且元素都是无序的。

HashSet 类在存储每个元素时先调用该元素的 hashCode() 方法生成一个唯一的整数标识——散列码(Hashcode),先根据散列码确定元素的存储位置,再调用元素对象的 equals() 方法来确保该位置没有重复元素。HashSet 类之所以能快速实现元素查询也与此有关。

定义 HashSet 类的语法格式如下:
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable
HashSet 类的构造方法如下:
HashSet 类的缺点是保存的元素没有特定顺序。Java 还提供了一种新的 HashSet 类——LinkedHashSet,该类通过一个链表来维护添加的元素的顺序,即遍历顺序和插入顺序是一致的。LinkedHashSet 类的所有方法与 HashSet 类的方法是一致的。

【实例】 HashSet集合的应用。
import java.util.HashSet;
public class Demo {
    public static void main(String[] args) {
        HashSet nameset = new HashSet<>();
        nameset.add("张三");
        nameset.add("李四");
        // 添加重复元素
        nameset.add("张三");
        // 输出 HashSet 集合
        System.out.println(nameset);
    }
}
运行结果如下:

[李四, 张三]

使用 add() 方法在 HashSet 集合中依次添加 3 个字符串元素并输出。由运行结果可知,取出元素的顺序与添加元素的顺序并不一致,并且重复存入的元素“张三”只输出一次。

HashSet 集合之所以能确保不出现重复的元素,是因为先后调用了 hashCode() 方法和 equals() 方法,执行过程是:当调用 HashSet 集合的 add() 方法存入元素时,首先调用当前存入元素的 hashCode() 方法获得对象的哈希值,然后根据对象的哈希值计算出一个存储位置。若该位置上没有元素,则直接将元素存入;若该位置上有元素,则调用 equals() 方法将当前存入的元素依次和该位置上的元素进行比较。如果返回的结果为 false,那么将该元素存入集合中;如果返回的结果为 true,说明有重复元素,那么将该元素舍弃。

当向集合中存入元素时,为了保证 HashSet 正常工作,要求在存入元素时重写 Object 类中的 hashCode() 方法和 equals() 方法。在上面实例中,将字符串存入集合中时,调用的是 String 类重写的 hashCode() 方法和 equals() 方法。但是如果将自定义类型的对象存入集合中,那么必须重写上述两个方法。

【实例】HashSet集合的应用——存入自定义类型的对象。
import java.util.HashSet;

class Student {
    String id;
    String name;
    public Student(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public String toString() {
        return id + ":" + name;
    }
}

public class Demo {
    public static void main(String[] args) {
        HashSet<Student> nameset = new HashSet<>();
        Student student1 = new Student("001", "张三");
        Student student2 = new Student("002", "李四");
        Student student3 = new Student("001", "张三");
        nameset.add(student1);
        nameset.add(student2);
        // 添加重复元素
        nameset.add(student3);
        // 输出 HashSet 集合
        System.out.println(nameset);
    }
}
运行结果如下:

[001:张三, 002:李四, 001:张三]

运行结果中出现了两条相同的学生信息,这样的学生信息被视为重复元素。为什么会出现这种情况呢?这是因为在定义 Student 类时没有重写 hashCode() 方法和 equals() 方法,创建的这两个学生对象 student1 和 student3 所引用的对象地址不同,所以被它们认为是两个不同的对象。

在上面实例的基础上,下面的实例修改了 Student 类,并且重写 hashCode() 方法和 equals() 方法,条件是 id 相同的学生就是同一个学生。

【实例】HashSet 集合的应用——存入自定义类型的对象,重写 hashCode() 方法和 equals() 方法。
import java.util.HashSet;

class Student {
    String id;
    String name;
    public Student(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public String toString() {
        return id + ":" + name;
    }
    // 重写hashCode()方法
    public int hashCode() {
        // 返回id属性的哈希值
        return id.hashCode();
    }
    // 重写equals()方法
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Student)) {
            return false;
        }
        Student student = (Student) obj;
        boolean boo = this.id.equals(student.id);
        return boo;
    }
}

public class Demo {
    public static void main(String[] args) {
        HashSet<Student> nameset = new HashSet<>();
        Student student1 = new Student("001", "张三");
        Student student2 = new Student("002", "李四");
        Student student3 = new Student("001", "张三");
        nameset.add(student1);
        nameset.add(student2);
        // 添加重复元素
        nameset.add(student3);
        // 输出HashSet集合
        System.out.println(nameset);
    }
}
运行结果如下:

[001:张三, 002:李四]

由运行结果可知,HashSet 集合认为 student1 和 student3 两个对象相同,因此删除了重复的元素。

相关文章