HashSet使用笔记

Set集合相较list集合具有无序,存储元素不可重复的特点.

这里简单记录下Set集合中HashSet在使用时需要主要的几点事项

1.HashSet集合底层使用的是哈希表数据结构,因此在查找的时候速度会非常快

2.集合中只可以存储对象,而不可以存储基本数据类型

private static void func4() {
        HashSet set = new HashSet();
        set.add(1);
        set.add(2);
        System.out.println(set);

        Iterator it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next() + "...");
        }
    }

既然只可以存储对象,那么这里为什么可以存储1这样的基本数据类型呢,这是因为这里对其做了一个自动装箱和自动拆箱的一个动作,

与下边这段代码是一致的效果:

private static void func5() {
        HashSet set = new HashSet();
        set.add(new Integer(1));
        set.add(new Integer(2));
        System.out.println(set);

        Iterator it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next() + "...");
        }
    }

3.存储元素的时候需要重新对象实例的hashCode()和equals()方法来确保存储的元素是唯一的

public class Person {

    private int age;
    private String name;

    public Person(String n, int a) {
        this.age = a;
        this.name = n;
    }


    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
}
 private static void func3(){
        HashSet<Person> people = new HashSet<>();
        people.add(new Person("张三", 22));
        people.add(new Person("李四", 20));
        people.add(new Person("张三", 22));
        System.out.println(people);

    }

例如上边两段代码执行的结果是people集合中有3个对象而不是2个,因为通过new关键字生成的对象都是一个新的对象,需要在内存中开辟独立地存储空间,具有独立地地址值.那么如何让pepole中只存有2个对象呢,这里就需要重写Person对象的hashCode()和equals()方法.hashCode值相同,需要通过equals判断具体内容是否相同,equals返回true时,hashSet集合判定这两个元素是相同元素,因此所以只会存储一个.

其原理简单说就是先判断hashCode值是否相同,只有在hashCode值相同的时候才会去调用equals方法,如果hashCode值不相同是不会去调用equals方法的.

public class Person {

    private int age;
    private String name;

    public Person(String n, int a) {
        this.age = a;
        this.name = n;
    }


    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
//        System.out.println(this.hashCode());
        return name.hashCode() + age * 23;
//        return 1;
    }


    @Override
    public boolean equals(Object obj) {
        //instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
        System.out.println("sssssssss");
        if (!(obj instanceof Person)) {
            return false;
        }

        Person p = (Person) obj;
        boolean b = this.name.equals(p.name) && this.age == p.age;

        return b;
    }
}

通过上边的代码即可实现我们去重的效果了,这里还有一个小技巧需要特别注意.

在重写的hashCode()方法中需要在返回值中加一个大于1的随机数,以达到hashCode值不重复的目的.

4.一个hashCode值上是也可以存在多个对象的,而非一个.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值