7.5 Set接口

 

7.5 Set接口

7.5.1 Set接口简介

Set接口是Java集合框架中的一个重要组成部分,它继承自Collection接口。Set接口的主要特点是它的元素是无序的,并且保证元素的唯一性,即不允许重复。这与List接口相比,List允许重复元素并且元素是有序的,形成了鲜明的对比。

Set接口的实现类

Set接口有几个常见的实现类:

  • HashSet:最常用的一种Set实现,它使用哈希表(实际上是一个HashMap实例)来存储元素。HashSet提供了很好的查找、获取和存储性能。
  • LinkedHashSet:类似于HashSet,但它使用链表维护元素的插入顺序,因此迭代访问Set时,元素的返回顺序是其插入顺序。
  • TreeSet:基于红黑树(一种自平衡的二叉查找树)实现,元素会按照自然排序(Natural Ordering)或创建Set时提供的Comparator进行排序。

7.5.2 HashSet

HashSet是Set接口的一个基本实现类,它确保集合中的元素不重复,主要通过以下步骤实现:

工作原理和用例

  1. 存储元素:当向HashSet中添加元素时,首先调用元素的hashCode()方法来计算元素的哈希码,这个哈希码决定了元素在HashSet中的存储位置。
  2. 检查重复:如果计算得到的位置已经有元素存在,HashSet会调用equals()方法来检查两个元素是否相同。如果equals()返回true,新元素不会被添加到集合中。
示例代码
import java.util.HashSet;
import java.util.Iterator;

public class Example07 {
    public static void main(String[] args) {
        HashSet<String> hset = new HashSet<>();
        hset.add("张三");
        hset.add("李四");
        hset.add("王五");
        hset.add("李四");  // 尝试添加重复元素

        Iterator<String> it = hset.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

运行结果和解释

在上述示例中,即便我们尝试将"李四"添加两次,输出结果也只会显示一次"李四"。这证明了HashSet不允许重复元素。输出顺序也可能与添加顺序不同,因为HashSet不保证元素的顺序。

注意事项

  • 自定义对象:如果在HashSet中使用自定义对象,你需要重写这个对象的hashCode()equals()方法,以确保HashSet能正确地识别重复元素。
  • 性能考虑:虽然HashSet在添加和查找元素时非常高效,但这种效率依赖于hashCode()方法的实现。一个糟糕的hashCode()实现会导致频繁的哈希冲突,从而降低性能。

HashSet是Java集合中广泛使用的一个组件,了解其工作原理对于实现基于性能的高效Java应用至关重要。

 

 

7.5.3 LinkedHashSet

介绍

在Java中,LinkedHashSetHashSet的一个子类,它结合了哈希表的快速访问特性和链表的顺序性。LinkedHashSet内部通过双向链表来维护元素的插入顺序,因此迭代访问LinkedHashSet时,元素的返回顺序与它们的插入顺序相同。

特点

  • 有序性:与HashSet不同,LinkedHashSet维护着一个运行于所有条目的双向链表。这使得迭代顺序是可预测的,即元素以它们被插入到集合中的顺序来迭代。
  • 性能LinkedHashSet在添加和删除元素时保持与HashSet相同的性能特征,即平均时间复杂度为O(1)。但是由于维护链表的开销,它的性能可能略低于HashSet
  • 内存使用:由于LinkedHashSet同时维护哈希表结构和链表结构,因此它比HashSet消耗更多的内存。

使用场景

LinkedHashSet适用于需要维护插入顺序的场景,例如缓存、先进先出(FIFO)的记录和记忆最近使用的项。

示例

以下是一个简单的LinkedHashSet应用示例,展示了如何创建和迭代这种类型的集合。

示例代码
import java.util.Iterator;
import java.util.LinkedHashSet;

public class Example10 {
    public static void main(String[] args) {
        LinkedHashSet<String> set = new LinkedHashSet<>();
        // 向集合中添加字符串
        set.add("张三");
        set.add("李四");
        set.add("王五");

        // 获取Iterator对象
        Iterator<String> it = set.iterator();
        // 通过while循环判断集合中是否有元素
        while (it.hasNext()) {
            String obj = it.next();
            // 调用Iterator的next()方法获取元素
            System.out.println(obj);
        }
    }
}

运行结果

该程序的输出将严格按照元素的添加顺序:

张三
李四
王五

结论

LinkedHashSet提供了一种强大的机制,用于保持集合中元素的插入顺序,同时还保持了哈希表的查询效率。这使得它在需要顺序访问时成为一个优于HashSet的选择。如果应用程序不需要维护插入顺序,那么使用HashSet可能更合适,因为它在内存使用上更为高效。

 

7.5.4 TreeSet

概述

TreeSet是Java集合框架中的一个实现Set接口的类,它使用红黑树(一种自平衡的二叉查找树)来存储元素。由于这种结构的特性,TreeSet能确保集合元素的排序以及高效的访问和查找性能。这使得TreeSet成为在需要排序集合时的理想选择。

特点

  • 元素唯一性: 如同其他Set实现,TreeSet不允许重复元素。
  • 自动排序: TreeSet中的元素在添加时会自动按照自然排序(即元素的自然顺序)或者根据构造器提供的Comparator进行排序。
  • 非同步: TreeSet是非同步的,如果多个线程同时访问一个TreeSet,并且至少有一个线程修改了集合,它必须保持外部同步。
  • 性能: 对于常见操作如添加、删除和查找元素,TreeSet提供了优秀的性能,时间复杂度为O(log n)。

使用场景

TreeSet适用于需要大量动态插入和需要有序访问集合的场合。例如,在一个排序的列表中维护无重复的错误代码或者用户ID等。

示例

以下是使用TreeSet的一个简单示例,演示如何添加元素以及如何利用其自动排序的特性。

示例代码
import java.util.TreeSet;

public class Example11 {
    public static void main(String[] args) {
        TreeSet<Integer> ts = new TreeSet<>();
        // 向集合中添加元素
        ts.add(29);
        ts.add(3);
        ts.add(101);
        ts.add(21);

        System.out.println("创建的TreeSet集合为:" + ts);

        // 获取并输出集合的首尾元素
        System.out.println("TreeSet集合首元素为:" + ts.first());
        System.out.println("TreeSet集合尾部元素为:" + ts.last());

        // 获取特定条件的元素
        System.out.println("集合中小于或等于9的最大的元素为:" + ts.floor(9));
        System.out.println("集合中大于10的最小的元素为:" + ts.higher(10));
        System.out.println("集合中大于100的最小的元素为:" + ts.higher(100));

        // 删除并输出第一个元素
        Object first = ts.pollFirst();
        System.out.println("删除的第一个元素为:" + first);
        System.out.println("删除第一个元素后TreeSet集合变为:" + ts);
    }
}
运行结果

输出将展示集合元素的自动排序,以及首尾元素的访问和条件查询的结果。例如:

创建的TreeSet集合为:[3, 21, 29, 101]
TreeSet集合首元素为:3
TreeSet集合尾部元素为:101
集合中小于或等于9的最大的元素为:3
集合中大于10的最小的元素为:21
集合中大于100的最小的元素为:101
删除的第一个元素为:3
删除第一个元素后TreeSet集合变为:[21, 29, 101]

总结

TreeSet是一个强大的集合类,适用于需要排序和高效访问的场景。它通过红黑树确保元素的顺序和快速访问,适合作为数据结构的一部分用于排序的需求。

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值