Set系列集合

在 Java 中,Set 是一个接口,表示一组不允许重复的元素。它继承自 Collection 接口。
主要实现类:
HashSetLinkedHashSetTreeSet

HashSet

HashSet 是基于 HashMap 实现的,其底层原理主要依赖于哈希表。

工作原理

哈希表结构
使用哈希表(数组加链表/红黑树)来存储元素。
元素通过计算哈希值找到在表中的位置。

添加元素
计算元素的哈希值,找到对应的桶位置。
如果该位置没有元素,则直接存储。
如果已有元素,使用链表(或红黑树)解决哈希冲突。

哈希冲突
当多个元素的哈希值相同时,使用链表存储冲突的元素。
在 Java 8 之后,当链表长度超过阈值时,转换为红黑树,提高查找效率。

查找和删除
通过哈希值快速定位到元素所在的桶。
在桶中遍历链表或红黑树,找到目标元素进行操作。

扩容机制
当元素数量超过负载因子(默认0.75)乘以当前容量时,HashSet 会扩容。
扩容时,重新计算所有元素的哈希值并分配到新的桶中。

特点
无序:元素插入顺序不被保证。

不允许重复:元素根据哈希值存储,重复元素会被覆盖。

高效操作:add、remove、contains 的时间复杂度为 O(1)(平均情况下)。

HashSet 适用于需要快速判断元素存在性和去重的场景,可以存储一个 null 元素。

public class test {
    public static void main(String[] args) {
        Set<Student> s = new HashSet<>();
        s.add(new Student("张三",32));
        s.add(new Student("李武", 23));
        s.add(new Student("张三",32));
        s.add(new Student("王阳", 44));
        System.out.println(s);//两个相同的张三全部输出
        //原因是两个对象的哈希值不同
    }
}

重写hashCode()和equls()函数可以合并两个属性值完全相同的对象。

   //属性相同即返回true
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }
    // 根据属性值生成哈希值
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

LinkedHashSet

LinkedHashSet 是 Java 集合框架中的一个类,继承自 HashSet,并通过维护一个双向链表来记录元素的插入顺序。

底层原理

基于 HashMap 实现
和 HashSet 一样,LinkedHashSet 的底层使用 HashMap 来存储元素。

维护插入顺序
通过一个双向链表记录元素的插入顺序。
每个元素在哈希表中的节点同时包含了链表中的指针,用于维护顺序。

哈希表和链表结合
元素存储在哈希表中以实现快速访问。
链表维护元素的插入顺序。

操作效率
插入、删除和查找的时间复杂度为 O(1)(平均情况下)。
保持了 HashSet 的性能优势,同时提供顺序维护功能。

特点
有序:元素按插入顺序存储。

不允许重复:每个元素在集合中唯一。

允许 null:可以包含一个 null 元素。

性能:插入、删除、查找的时间复杂度为 O(1)(平均情况下),但略低于 HashSet 因为维护了顺序。

        Set<Integer> s = new LinkedHashSet<>();
        s.add(11);
        s.add(34);
        s.add(25);
        s.add(11);
        s.add(61);
        s.add(9);
        System.out.println(s);//[11, 34, 25, 61, 9]
        //输出顺序和添加顺序相同

TreeSet

TreeSet 是 Java 中的一个集合类,基于 NavigableSet 接口和 AbstractSet 类实现,底层依赖于 TreeMap,使用红黑树来存储元素。

特点
有序性:

元素按自然顺序排序(降序),或根据提供的 Comparator 进行排序。
适合需要排序的场景。

不允许重复:
每个元素在集合中唯一。

不允许 null 元素:
因为需要进行排序比较。

        Set<Integer> s = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
        s.add(11);
        s.add(34);
        s.add(25);
        s.add(11);
        s.add(61);
        s.add(9);
        System.out.println(s);//[61, 34, 25, 11, 9]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值