HashSet如何确保元素不重复?

  • 1.HashSet原理:
  • 当我们使用Set集合都是需要去掉重复元素的,如果在存储的时候逐个equals()比较,效率较低,哈希算法
  • 提高类去重复的效率,降低了equals()的使用次数
  • 当HashSet调用add()方法存储对象的时候,先调用对象的hashCode()方法,然后在集合中查找是否有哈希值相同的对象
    • 如果没有哈希值相同的对象就直接存入集合
    • 如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals()笔记,比较结果为false就存入,true则不存
  • 2.将自定义类的对象存入HashSet去重复
    • 类中必须重写hashcode()和equals()方法
    • hashcode():属性相同的返回值必须相同,属性不同的返回值尽量不同(提高效率)
    • equals():属性相同返回true,属性不同返回false,返回false的时候存储

定义的Person类

package com.melody.bean;
public class Person {
    private String name;
    private int age;
    /**
     *
     */
    public Person() {
        super();

    }
    /**
     * @param name
     * @param age
     */
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return the age
     */
    public int getAge() {
        return age;
    }
    /**
     * @param age the age to set
     */
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    /**
     * 为什么是31?
     * 1.31是一个质数,质数是能被1和自己本身整除的数
     * 2.31这个数不大不小
     * 3.31这个数好算2的5次方-1,2向左移动五位
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

下面的是测试类:

package com.melody.set;

import java.util.HashSet;

import com.melody.bean.Person;

public class Demo1_HashSet {
    /**
     * @param args
     * Set集合,无索引,不可以重复,无序(存取不一致)
     */
    public static void main(String[] args) {
//        test1();
        HashSet hs = new HashSet<>();
        hs.add(new Person("张三", 23));
        hs.add(new Person("李四", 24));
        hs.add(new Person("张三", 23));
        hs.add(new Person("李四", 24));
        hs.add(new Person("李四", 23));

        //添加引用数据类型时,若要不重复,需要重写HashCode和equals方法
        System.out.println(hs.size());
        System.out.println(hs);
    }

    private static void test1() {
        HashSet hs = new HashSet<>();
        hs.add("ce");
        boolean b1 = hs.add("a");
//        boolean b2 = hs.add("a");
        hs.add("b");
        hs.add("c");
        hs.add("d");
        //HashSet 当向set集合中存储重复元素会返回false
        //HashSet 的继承体系中有重写set方法
//        System.out.println("b1 = " + b1 + " b2 = " + b2);
        System.out.println(hs);

        //可以用迭代器方法就可以使用增强for循环
        for (String string : hs) {
            System.out.println(string);
        }
    }

}

你可能感兴趣的:(HashSet如何确保元素不重复?)