Set接口

java.util.Set接口和java.util.List接口是一样的,都是继承自Collection接口,它与Collection接口中的方法基本一样,没有对Collection接口进行功能上的扩展,只是比Collection接口更加严厉。与List接口不同的是,Set接口中的元素是无序的,并且都会以某种规则存入的元素不重复

  • Set接口有很多个子类,我们主要介绍两个重要子类:java.util.HashSet和java.util.LinkedHashSet集合
  • Set集合取出的元素的方式可以采用:迭代器、增强for循环
HashSet集合介绍
  • java.util.HashSet是Set接口的一个实现类,它存储的元素是不可重复的,并且元素都是一个无需的(存取顺序不一致)。java.util.HashSet底层的实现其实是一个java.util.HashMap支持的。
  • HashSet是根据对象的哈希值来确定元素在集合当中的存储位置,因此它具有良好的存取和查找性能。保证元素唯一性的方式依赖于hashCodeequals方法
    实例代码:
/**
 * java.util.Set.extends Collection接口
 * Set接口的特点:
 *         1、不允许存储重复性的元素
 *         2、没有索引,没有带索引的方法,也不能使用普通的for循环进行遍历
 *   java.util.HashSet implements Set 接口
 *   HashSet集合的特点:
 *         1、不允许存储重复性的元素
 *         2、没有索引,没有带索引的方法,也不能使用普通的for循环进行遍历
 *         3、是一个无序的集合,存储的元素顺序和取出元素的顺序可能不一致
 *         4、底层是一个哈希结构(查询)
 */
public class SetDemo01 {
    public static void main(String[] args) {
        //构建Set集合
        Set<Integer> set = new HashSet<>();
        //使用add方法往集合当中存储一些元素
        set.add(123);
        set.add(125);
        set.add(120);
        set.add(123);
        //查看set集合当中的元素
        Iterator<Integer> iterator = set.iterator();
        while (iterator.hasNext()){
            Integer num = iterator.next();
            System.out.println(num);
        }
        System.out.println("------------------------");
        for (Integer integer : set) {
            System.out.println(integer);
        }
    }
HashSet集合存储数据的结构(哈希表)
  • 什么是哈希表呢?

  • 在JDK1.8之前,哈希表的底层采用的是数组+链表实现,即使用链表处理哈希冲突,同一哈希值的链表都存储在一个链表里,但是当位于一个链中的元素较多时,即hash值相等的元素较多时,通过key值依次查找的效率很低下。在JDK1.8中,哈希表存储结构采用数组+链表/红黑树实现的,当链表的长度超过阈值(8)时,将链表转换成红黑树结构,这样的好处是大大减少了查找的时间
    如图展示:
    在这里插入图片描述

  • 总而言之,JDK1.8之后引入红黑树结构大大优化了HashMap的性能,那么对于我们来讲保证HashSet元素唯一不重复,其实是根据对象的hashCode和equals方法来决定的。如果我们往集合当中存储的是自定义的对象,需要保证对象的唯一性,就必须重写HashCode和equals方法,来自定义当前对象的比较方式。

HashSet存储自定义类型的元素
  • 一般需要重写对象当中的hashCode和equals方法,建立自己的比较方式。才能保证HashSet集合中元素的唯一性。
    代码例子如下:
    例如自己构建一个对象:
    没有重写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
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    
}

进行比较对象:

        //创建一个HashSet集合对象
        HashSet<Student> hashSet = new HashSet<>();
        //构建多个学生对象
        Student s1 = new Student("小孙", 21);
        Student s2 = new Student("小孙", 21);
        Student s3 = new Student("小孙", 21);
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());

        System.out.println(s1==s2);//fasle
        System.out.println(s1.equals(s2));//false

        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);

        System.out.println(hashSet);
    }

结果如下:
在这里插入图片描述

重写后equals方法和hashcode方法后的比较
代码如下:

//自定义的Student类重写的hashCode和equals方法
@Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (this == o) {
            return true;
        }
        if (o instanceof Student) {
            Student student = (Student) o;
            //同名同年龄的人为同一个人 true
            return student.getName().equals(name) && student.getAge() == age;
        }
        return false;
    }
    @Override
    public int hashCode(){
        //使用工具类objects中的hash方法
        return Objects.hash(name,age);
    }

演示结果如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值