首页 > 其他分享 >List,Set,Queue,Map接口

List,Set,Queue,Map接口

时间:2024-08-06 11:16:23浏览次数:17  
标签:Map Set 队列 元素 List 接口 Queue 线程

List,Set,Queue,Map接口

一.List接口

List 接口是 Java 集合框架中的一个重要接口,它继承自 Collection 接口。List 接口表示一个有序的集合,其中的元素可以重复。这意味着在 List 中,每个元素都有一个特定的索引位置,我们可以通过这个索引来访问或操作元素。

List 接口的主要特点包括:

  1. 有序性List 集合中的元素是按照它们被插入的顺序来存储的。可以通过索引来访问集合中的元素。
  2. 允许重复元素:与 Set 接口不同,List 允许存储重复的元素。
  3. 提供额外的方法:除了从 Collection 接口继承的方法外,List 接口还定义了一些用于插入、删除和访问列表元素的方法,比如 get(int index)add(int index, E element)remove(int index) 等。

List 接口的实现类主要包括:

  • ArrayList:基于动态数组的数据结构实现的列表。它允许快速的随机访问,但在列表的末尾之外的位置插入或删除元素时可能较慢,因为可能需要移动元素。
  • LinkedList:基于链表的数据结构实现的列表。它在列表的开头和结尾进行插入和删除操作非常快速,但在随机访问方面不如 ArrayList
  • Vector:是一个古老的 List 实现,它是同步的,但通常不推荐使用,因为性能较低,并且大多数需要同步的情况都可以通过使用 Collections.synchronizedList 方法将任何 List 包装成同步的列表来更灵活地处理。
  • Stack:是 Vector 的一个子类,实现了后进先出(LIFO)的堆栈。不过,Stack 类被认为是过时的,Java 提供了 Deque 接口(及其实现类如 ArrayDeque)作为更现代的替代方案,以提供更强大的双端队列功能,同时也支持堆栈操作。

以下是一些 List 接口的常用方法:

  • boolean add(E e):向列表的末尾添加指定的元素。
  • void add(int index, E element):在列表的指定位置插入指定的元素。
  • E get(int index):返回列表中指定位置的元素。
  • E remove(int index):移除列表中指定位置的元素,并返回被移除的元素。
  • E set(int index, E element):用指定的元素替换列表中指定位置的元素,并返回原来位置的元素。
  • int size():返回列表中的元素数量。

由于 List 接口是有序的,并且提供了基于索引的访问和操作方法,因此它非常适合用于需要频繁进行插入、删除和访问操作的场景。

二.Set接口

Set 接口是 Java 集合框架中的一个重要接口,它继承自 Collection 接口,用于表示不包含重复元素的集合。以下是对 Set 接口的详细介绍:

1.接口定义与特点

  • 接口定义Set 接口是 Java 中的一个接口,它位于 java.util 包中,用于表示不包含重复元素的集合。

  • 特点

    1. 互异性Set 集合中的任何两个元素都不相同,即每个元素只能出现一次。
    2. 无序性Set 集合中的元素是无序的,即集合不保证元素的任何特定顺序。但请注意,某些 Set 的实现(如 LinkedHashSet)可能会保持元素的插入顺序。
    3. 不包含重复元素Set 接口确保集合中不包含重复的元素。

2.主要实现类

Set 接口有几个主要的实现类,包括但不限于:

  • HashSet:基于哈希表实现,提供快速的元素插入和查找操作,但不保证集合的迭代顺序。
  • LinkedHashSetHashSet 的一个子类,它维护了一个运行于所有条目的双向链表,从而按照插入顺序来遍历元素。
  • TreeSet:基于红黑树实现,能够确保集合元素处于排序状态。默认情况下,元素按照自然顺序排序,但也可以指定自定义的比较器进行排序。

3.常用方法

Set 接口继承了 Collection 接口的所有方法,并添加了一些自己的方法(虽然实际上在 Set 接口中并没有定义额外的方法,因为 Set 本身就是 Collection 的一种特殊形式)。以下是一些常用的 Set 方法:

  • boolean add(E e):将指定的元素添加到集合中(如果尚未存在)。
  • boolean remove(Object o):从集合中删除指定的元素(如果存在)。
  • boolean contains(Object o):检查集合是否包含指定的元素。
  • int size():返回集合中的元素数量。
  • boolean isEmpty():检查集合是否为空。
  • void clear():清空集合中的所有元素。
  • Iterator<E> iterator():返回一个迭代器,用于遍历集合中的元素。

4.使用场景

Set 接口及其实现类在 Java 编程中有广泛的应用场景,特别是在需要存储不重复元素的集合时。例如,可以使用 Set 来跟踪唯一的标识符、在算法中保持唯一元素的集合、或者作为数据结构的基础来构建更复杂的数据结构等。

5.注意事项

  • 由于 Set 集合不保证元素的顺序,因此在需要有序集合时,应该选择如 LinkedHashSetTreeSet 这样的实现类。
  • 在使用 TreeSet 时,如果元素类型没有实现 Comparable 接口或者没有提供自定义的比较器,那么在添加元素时可能会抛出 ClassCastExceptionNullPointerException
  • Set 接口的实现类(如 HashSet)通常不是同步的,如果在多线程环境中使用,需要外部同步或选择同步的集合类(如 Collections.synchronizedSet)。

三.Queue接口

在Java中,Queue接口是一种用于表示队列数据结构的接口,它位于java.util包中。队列是一种先入先出(FIFO,First-In-First-Out)的数据结构,新元素被添加到队列的末尾,而访问元素(移除元素)则发生在队列的开头。Queue接口继承自Collection接口,并扩展了队列的操作。

非阻塞队列是Queue接口的一种实现,它在操作队列时不会阻塞当前线程。如果尝试向已满的非阻塞队列中添加元素,或者从空队列中移除元素,这些操作通常会立即返回一个结果或抛出异常,而不是使线程等待。

非阻塞队列实现:

1. LinkedList

  • 实现:基于双向链表实现的ListDeque接口。
  • 特点:允许包含null元素,并且是非同步的。它实现了所有可选的列表操作,并允许包括null在内的所有元素。除了实现List接口外,LinkedList还提供了双端队列的功能,即可以从两端添加和移除元素。
  • 使用场景:适用于需要频繁在列表两端进行插入和删除操作的场景。由于它是基于链表的,因此在这些操作上通常比基于数组的列表(如ArrayList)要快。

2. ArrayDeque

  • 实现:基于数组的双端队列。
  • 特点:是一个先进先出(FIFO)的队列,可以从两端插入和移除元素。它是非阻塞的,且非同步的。与LinkedList相比,ArrayDeque在大多数队列操作(特别是随机访问)上通常具有更好的性能,因为它减少了节点分配的开销。
  • 使用场景:适用于需要高性能双端队列操作的场景。

3. PriorityQueue

  • 实现:基于优先级堆的一个无界优先级队列。
  • 特点:元素的排序是根据其自然顺序或构造队列时提供的Comparator来确定的。队列的头部是队列中优先级最高的元素。PriorityQueue不允许null元素,且不是线程安全的。
  • 使用场景:适用于需要根据元素的优先级来检索元素的场景。例如,任务调度、事件处理等。

4. ConcurrentLinkedQueue

  • 实现:基于链接节点的无界线程安全队列。
  • 特点:使用非阻塞算法来实现高并发级别下的线程安全。它采用CAS(Compare-And-Swap)操作来确保线程安全,而不需要进行外部同步。ConcurrentLinkedQueue是FIFO的,并且是无界的,这意味着它可以无限期地增长。
  • 使用场景:适用于高并发环境下的非阻塞队列操作。它避免了在多线程环境下使用LinkedList时可能遇到的同步问题。

总结

  • 如果你需要一个高性能的双端队列,并且不需要线程安全,那么ArrayDeque可能是最好的选择。
  • 如果你需要一个基于链表的队列,并且需要频繁在两端进行插入和删除操作,那么LinkedList是合适的。
  • 如果你需要根据元素的优先级来检索元素,那么PriorityQueue是最佳选择。
  • 如果你在高并发环境下需要一个线程安全的非阻塞队列,那么ConcurrentLinkedQueue将是理想的选择。

阻塞队列实现:

在Java的并发编程中,ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueueDelayQueueSynchronousQueueLinkedTransferQueueLinkedBlockingDeque是几种常见的阻塞队列实现,它们各自具有不同的特性和应用场景。以下是对这些队列的详细解析:

1. ArrayBlockingQueue

  • 特性:基于数组结构的有界阻塞队列,按FIFO(先进先出)原则对元素进行排序。
  • 应用场景:适合用于那些需要固定大小缓冲区的场景,如生产者-消费者模式中的缓冲区。
  • 线程安全性:通过内部锁机制保证线程安全。
  • 阻塞行为:当队列满时,添加元素的操作会阻塞;当队列空时,移除元素的操作会阻塞。

2. LinkedBlockingQueue

  • 特性:基于链表结构的阻塞队列,按FIFO排序元素,吞吐量通常高于ArrayBlockingQueue
  • 应用场景:适用于高并发环境下的生产者-消费者模式,可作为任务队列使用。
  • 线程安全性:内部使用锁和条件变量保证线程安全。
  • 容量:可选容量,默认为Integer.MAX_VALUE,即几乎无界。

3. PriorityBlockingQueue

  • 特性:基于数组的优先级阻塞队列,无界,每次出队都返回优先级最高的元素。
  • 应用场景:适合需要按照优先级顺序处理任务的场景。
  • 排序:元素可以根据自然顺序或构造时指定的Comparator进行排序。
  • 线程安全性:内部使用锁和条件变量保证线程安全。

4. DelayQueue

  • 特性:无界阻塞队列,用于放置实现了Delayed接口的对象,其中的元素只能在其指定的延迟时间到了之后才能从队列中取走。
  • 应用场景:适合缓存失效管理、任务调度等场景。
  • 线程安全性:内部使用PriorityQueue实现,并保证了线程安全。

5. SynchronousQueue

  • 特性:不存储元素的阻塞队列,每个插入操作必须等待另一个线程调用移除操作,否则插入操作一直处于阻塞状态。
  • 应用场景:适用于传递性场景,如线程间的直接手递手传递。
  • 线程安全性:内部使用锁和条件变量保证线程安全。

6. LinkedTransferQueue

  • 特性:基于链表结构的无界阻塞TransferQueue,相比LinkedBlockingQueue增加了非阻塞的转移方法。
  • 应用场景:适用于高并发环境下的复杂生产者-消费者场景,支持多个消费者。
  • 线程安全性:内部使用锁和条件变量保证线程安全。

7. LinkedBlockingDeque

  • 特性:基于链表结构的双端阻塞队列,支持在两端插入和移除元素。
  • 应用场景:适用于需要从队列两端进行操作的场景,如栈和队列的混合使用。
  • 线程安全性:内部使用锁和条件变量保证线程安全。

总结

以上七种阻塞队列各有其特点和适用场景,开发者在选择时应根据具体需求进行评估和选择。例如,如果需要固定大小的缓冲区,则可以选择ArrayBlockingQueue;如果需要无界且按优先级排序的队列,则可以选择PriorityBlockingQueue;如果需要按延迟时间处理元素,则可以选择DelayQueue等。同时,这些队列都提供了线程安全的保证,使得在多线程环境下使用更加安全可靠。

四.Map接口

在Java中,HashMapTreeMapLinkedHashMapConcurrentHashMapIdentityHashMapHashtable都是用于存储键值对的集合框架中的类,但它们各自具有不同的特性和用途。下面将简要介绍每个类的特点和用途:

  1. HashMap
    • HashMap是基于哈希表的Map接口的非同步实现。它允许使用null值和null键。
    • 它不保证映射的顺序;特别是,它不保证该顺序会随时间保持不变。
    • 它是基于哈希表的,因此其查找、插入和删除操作的平均时间复杂度为O(1)。
  2. TreeMap
    • TreeMap是基于红黑树(Red-Black tree)的NavigableMap实现。
    • 它能够按照自然顺序或者构造时所提供的Comparator进行排序。
    • TreeMap不允许使用null键;null值是可以的,但只能有一个。
    • 它保证了键的顺序是升序的,无论是自然顺序还是通过Comparator指定的顺序。
  3. LinkedHashMap
    • LinkedHashMapHashMap的一个子类,它维护着一个运行于所有条目的双重链接列表。
    • 这个链接列表定义了迭代器的遍历顺序,即按照元素被插入的顺序或最近最少使用的顺序(LRU)进行遍历。
    • 它允许使用null键和null值。
  4. ConcurrentHashMap
    • ConcurrentHashMap是专为并发环境设计的,它实现了ConcurrentMap接口。
    • 它通过分段锁(在Java 8及更高版本中通过CAS操作和synchronized块优化)提供了比Hashtable更高的并发级别。
    • 它不允许使用null键和null值。
    • 它的迭代器提供了弱一致性的视图,这反映了某一时间点或者迭代开始时的集合状态,而不是实时的集合状态。
  5. IdentityHashMap
    • IdentityHashMap使用==而不是equals()方法来比较键。
    • 这意味着对于两个对象,即使它们的内容相同(即equals()方法返回true),但如果它们在内存中的位置不同,它们将被视为不同的键。
    • 它允许使用null键和null值。
  6. Hashtable
    • Hashtable是同步的,它实现了Map接口。
    • 它不允许使用null键和null值。
    • 它是基于哈希表的,但与HashMap相比,它的所有方法都是同步的,这意味着它在多线程环境下是线程安全的,但可能会导致性能下降。
    • 它继承自Dictionary类,是Java早期的一个集合类,现在通常建议使用ConcurrentHashMap来代替它,以获得更好的并发性能。

总结:

  • 对于需要排序的Map,使用TreeMap
  • 对于需要保持插入顺序的Map,使用LinkedHashMap
  • 对于并发环境下的Map,使用ConcurrentHashMap
  • 如果需要根据对象的内存地址(而非equals()方法)来比较键,使用IdentityHashMap
  • 对于需要线程安全的Map,但在Java 8及以上版本,推荐使用ConcurrentHashMap而不是Hashtable,因为ConcurrentHashMap提供了更好的并发性能和灵活性。

标签:Map,Set,队列,元素,List,接口,Queue,线程
From: https://www.cnblogs.com/yhy373286277/p/18344781

相关文章

  • 数据结构 Queue 队列 -- C语言实现
    队列队列的概念队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特点FIFO(FirstInFirstOut)入队:进行插入操作的一端称为队尾出队:进行删除操作的一端称为队头链实栈代码实现Ququq.h#pragmaonce#define_CRT_SECURE_NO_WARNI......
  • verilog signed to unsigned offset binary
    verilogsignedtounsignedoffsetbinary背景有符号数据的最高bit是符号位,通常有符号数据都用补码来表示。补码就是该数绝对值的原码取反再加1得到,取补码的原因是为了把减法操作变成加法操作,便于电路实现。但是在HDL语言中处理有符号数据比较麻烦,HDL更习惯于无符号数据,无......
  • 【题解】Solution Set - 新高一矩阵选讲「陶治霖」
    新高一矩阵选讲「陶治霖」https://www.becoder.com.cn/contest/5348「CF1970E3」Trails(Hard)考虑DP。定义\(f_{i,j}\)表示,第\(i\)天走到\(j\)的方案数。有转移:\[f_{i,j}=\sum_{k=1}^mf_{i-1,k}\times(s_jl_k+s_kl_j+s_js_k)\]https://www.luogu.com.cn/article/i......
  • 记一次STM32使用I2C PinRemap引脚重映射出现卡死现象
    在移植WouoUI到STMF103C8BluePillboard时,发现会出现上电卡死在I2C检查函数(如下图)本人遇到的现象:在习惯使用的(SWI2C/HWI2C)@(PB8->SCLPB9->SDA)连接OLED的情况下,大多数情况使用江科大的SWI2C,一切正常。今天跑某开源基于u8g2库的UI框架WouoUI(HWI2C)@(PB6->SCLPB7->SDA)遇......
  • WPF locate discreted points via periodically and set transparency via the alpha,
    //xaml<Windowx:Class="WpfApp229.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.mi......
  • 【数据结构】Map和Set
    目录1.前言2.搜索树2.1概念2.2操作-查找2.3操作-插入2.4操作-删除2.5性能分析3.搜索3.1概念及场景3.2模型3.3Map的使用3.3.1关于Map的说明3.3.2关于Map.Entry的说明,>3.3.3Map的常用方法说明3.3.4TreeMap的使用3.4Set的使用3.4.1Set的说明3.4.2Set的常......
  • WPF WriteableBitmap通过GDI+绘制帮助类
    代码:publicclassWriteableBitmapGraphic:IDisposable{publicWriteableBitmapSource{get;privateset;}publicSystem.Drawing.Bitmapbitmap{get;privateset;}publicintDataLength{get;privateset;}publ......
  • 出现 No mapping for DELETE/GET等
    出现NomappingforDELETE/GET等错误一:请求url不对修改前如下图可知后端请求url为http://localhost:8080/user/addressBook运行后控制台出现发现后端请求url比前端请求url少了/改正:在@DeleteMapping后面加上/ @DeleteMapping("/")@ApiOperation("根据id......
  • python 元类:在调用“__set_name__”方法后编辑命名空间?
    假设我们用元类定义一个类。在类主体中,分配了对象,这些对象实现__set_name__以在类的数据结构中注册自身。是否可以在运行方法之后编辑命名空间?比如,分离填充的数据结构,将其分成两部分,然后在新属性下添加部分?__set_name__问题在于,在元类中调用之......
  • 模拟实现 memset --浅谈C语言
    memset()描述C库函数void*memset(void*str,intc,size_tn)用于将一段内存区域设置为指定的值。memset()函数将指定的值c复制到str所指向的内存区域的前n个字节中,这可以用于将内存块清零或设置为特定值。在一些情况下,需要快速初始化大块内存为零或者特定值,memse......