当前位置: 首页 > article >正文

【数据结构】Java 集合 Set 接口及其实现类的定义简介

接口继承接口,类实现接口。

Set 是一个接口,实现了 Collection 接口(都带有泛型)。它可以被继承或实现。在Java 集合章节的知识点中,学习其子类对象的实现以及关系。

类关系图

可以在IDEA中直接生成

Set 类关系图
集合 Set 类关系图

<interface> Set

集合 Set 均是非线程安全的。

public interface Set<E> extends Collection<E> {
    // Query Operations
}

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.

顾名思义,此接口对数学集抽象进行建模。

一个不含重复元素的集合,即任意元素使用equals函数比较时都返回false。

interface Set intro
Set 接口简介

常用的 Set 实现类有:

  • TreeSet
  • HashSet
    • LinkedHashSet 是 HashSet 的子类
public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable {}
public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {}
public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {}
Set 接口与各实现类的关系类图
Set 接口与各实现类的关系类图

实现类 TreeSet

非线程安全的

TreeSet Class intro
TreeSet 类简介

实现类 HashSet

HashSet Class intro
HashSet 类简介

实现类 LinkedHashSet

Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set. (An element e is reinserted into a set s if s. add(e) is invoked when s. contains(e) would return true immediately prior to the invocation.)

This implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet, without incurring the increased cost associated with TreeSet. It can be used to produce a copy of a set that has the same order as the original, regardless of the original set's implementation:
      void foo(Set s) {
          Set copy = new LinkedHashSet(s);
          ...
      }

A linked hash set has two parameters that affect its performance: initial capacity and load factor. They are defined precisely as for HashSet. Note, however, that the penalty for choosing an excessively high value for initial capacity is less severe for this class than for HashSet, as iteration times for this class are unaffected by capacity.

LinkedHashSet 虽然继承 HashSet ,但跟 HashSet 有差别:

  • 其内维护了一个双向链表(doubly-linked),有序插入。
  • 可以传入Set参数直接创建 LinkedHashSet 对象为原始 Set 的副本,构造方法如下:
    /**
     * Constructs a new linked hash set with the same elements as the
     * specified collection.  The linked hash set is created with an initial
     * capacity sufficient to hold the elements in the specified collection
     * and the default load factor (0.75).
     *
     * @param c  the collection whose elements are to be placed into
     *           this set
     * @throws NullPointerException if the specified collection is null
     */
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }
  • LinkedHashSet 和 HashSet 都有两个影响性能的参数:初始容量capacity  load factor。但是 LinkedHashSet 因为自身的迭代时间不受容量的影响(内部定义了迭代器方法),所以初始容量选择过高值的损失比 HashSet 要轻。
    • 迭代器只能尽力抛出ConcurrentModificationException,但不能完全保证非线程安全的 LinkedHashSet 可以不在并发场景中出问题。
    /**
     * Constructs a new, empty linked hash set with the specified initial
     * capacity and load factor.
     *
     * @param      initialCapacity the initial capacity of the linked hash set
     * @param      loadFactor      the load factor of the linked hash set
     * @throws     IllegalArgumentException  if the initial capacity is less
     *               than zero, or if the load factor is nonpositive
     */
    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }

    /**
     * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
     * and <em>fail-fast</em> {@code Spliterator} over the elements in this set.
     *
     * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
     * {@link Spliterator#DISTINCT}, and {@code ORDERED}.  Implementations
     * should document the reporting of additional characteristic values.
     *
     * @implNote
     * The implementation creates a
     * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
     * from the set's {@code Iterator}.  The spliterator inherits the
     * <em>fail-fast</em> properties of the set's iterator.
     * The created {@code Spliterator} additionally reports
     * {@link Spliterator#SUBSIZED}.
     *
     * @return a {@code Spliterator} over the elements in this set
     * @since 1.8
     */
    @Override
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
    }

Note that this implementation is not synchronized. If multiple threads access a linked hash set concurrently, and at least one of the threads modifies the set, it must be synchronized externally. This is typically accomplished by synchronizing on some object that naturally encapsulates the set. If no such object exists, the set should be "wrapped" using the Collections. synchronizedSet method. This is best done at creation time, to prevent accidental unsynchronized access to the set:
    Set s = Collections. synchronizedSet(new LinkedHashSet(...));

LinkedHashSet 是非同步的,即非线程安全的。如果多线程并发操作 LinkedHashSet 并至少有一个线程修改了此哈希集,则必须在外部同步该数据。

  • 通常在自然封装的集合的某个对象上进行同步
  • 如果不存在此类对象,则应该使用如下Collections 类的方法同步,最好在创建对象时就执行操作,以避免不同步访问Set的不同步造成异常
 Set s = Collections. synchronizedSet(new LinkedHashSet(set));
LinkedHashSet 类简介
LinkedHashSet 类简介


http://www.kler.cn/a/384915.html

相关文章:

  • JAVA笔记 | ResponseBodyEmitter等异步流式接口快速学习
  • 系统规划与管理师——第十二章 职业素养与法侓法规
  • Linux基础-1
  • 企业级-实现Redis封装层
  • 数组类算法【leetcode】
  • 使用代理时Stable Diffusion无法正常下载各类模型的解决办法
  • 测试-正交表与工具pairs的介绍使用(1)
  • Qt字符编码
  • Matlab实现海马优化算法(SHO)求解路径规划问题
  • 倒计时3天 | 2024 CCF中国开源大会仪式解读
  • 高级AI记录笔记(一)
  • [卷积神经网络]使用YOLOv11训练自己的模型
  • SQL,力扣题目1709,访问日期之间最大的空档期
  • Oceanbase学习之一迁移mysql数据到oceanbase
  • 基于SSM的校园美食交流系统【附源码】
  • 缓存-基础概念
  • (蓝桥杯C/C++)——基础算法(下)
  • 【大模型推理加速技术】SIMD 与SIMT
  • leetcode:杨辉三角
  • 计算机网络:网络层 —— 网络地址转换 NAT
  • python datetime模块
  • C# 几个基础位运算
  • 如何获取另外一个APP内部控件的图片资源,而非网页内的图片,攻略来喽
  • JavaCV 图像边缘检测 之 Sobel算子 算法
  • AI驱动无人驾驶:安全与效率能否兼得?
  • DBAPI连接阿里云 maxcompute 报错