Java 集合框架

目录

一、主要接口及实现类的特点

(1)Collection接口:

(2)List接口:

1.ArrayList:

2.LinkedList:

3.Vector:

4.Stack:

(3)Set接口:

1.HashSet:

2.LinkedHashSet:

3.TreeSet:

4.EnumSet:

5.CopyOnWriteArraySet:

(4)Queue接口:

一、ArrayDeque

二、LinkedList

三、PriorityQueue:

总结:

(5)Map接口:

1.HashMap:

2.LinkedHashMap:

3.TreeMap:

4.WeakHashMap:

5.IdentityHashMap:

6.SortedMap:

7.NavigableMap:

8.Hashtable:

9.ConcurrentHashMap:

(6)接口与实现类的关系

[三、Java 中不同集合类的性能的比较](#三、Java 中不同集合类的性能的比较)

[(一)、ArrayList 和 LinkedList](#(一)、ArrayList 和 LinkedList)

[(二)、HashSet、LinkedHashSet 和 TreeSet](#(二)、HashSet、LinkedHashSet 和 TreeSet)

[(三)、HashMap、LinkedHashMap 和 TreeMap](#(三)、HashMap、LinkedHashMap 和 TreeMap)

[(四)、Vector 和 ArrayList](#(四)、Vector 和 ArrayList)

四、集合类的工具类

Arrays.asList():

Collections.singletonXXX()和Collections.emptyXXX():

五、Map和Collection接口联系:

(一)、都是集合框架的一部分

(二)、可以相互转换

(三)、在某些操作上有相似性


Java 集合框架是为了表示和操作 一组对象而设计的统一体系结构。它提供了一组接口和实现类,使得开发者可以方便地存储、检索和操作数据集合。

一、主要接口及 实现类的特点

(1)Collection接口:

这是集合框架的根接口 ,它代表一组对象,称为元素。

子接口有**List、Set和Queue**等。

(2)List接口:

是一个有序 的集合,可以包含重复的元素。

允许通过索引 访问元素,支持随机访问。

常见的实现类有ArrayList、LinkedList和Vector。

1.ArrayList:

基于动态数组实现,随机访问元素速度快。

插入和删除元素在中间位置时效率较低,因为需要移动后续元素。

2.LinkedList:

基于双向链表实现。

插入和删除元素速度快,特别是在列表中间位置。

随机访问元素相对较慢,需要遍历链表。

3.Vector:

与ArrayList类似,但线程安全,性能相对较低。

4.Stack:

它是一种特殊的Vector,实现了后进先出(LIFO)的数据结构。

提供了push(入栈)、pop(出栈)、peek(查看栈顶元素)等方法。

(3)Set接口:

集合中的元素不能重复。

不保证 元素的存储顺序。

常见的实现类有HashSet、LinkedHashSet和TreeSet。

1.HashSet:

使用哈希表实现。

元素的存储顺序取决于哈希值,不保证顺序。

查找元素速度快。

2.LinkedHashSet:

维护了元素的插入顺序。

同时具有哈希表的快速查找和链表的顺序特性。

3.TreeSet:

基于红黑树实现,元素自动排序。

不允许插入重复元素。

4.EnumSet:

是一个专门为枚举类型设计的集合类。

内部使用位向量实现,非常高效,并且只能存储同一枚举类型的元素。

5.CopyOnWriteArraySet:

是一个线程安全的集合类,适用于读多写少的并发场景。

内部使用CopyOnWriteArrayList实现,在进行写操作时会创建一个新的副本,避免了并发修改的问题。

(4)Queue接口:

用于模拟队列 数据结构,遵循**先进先出(FIFO)**原则。

常见的实现类有LinkedList(可作为队列使用)、PriorityQueue等。

Deque

在 Java 中,Deque是一个双端队列接口 ,它既可以作为队列使用(先进先出,FIFO),也可以作为栈使用(后进先出,LIFO)。ArrayDeque和LinkedList是实现Deque接口的两个常用类。

一、ArrayDeque

  1. 底层数据结构:

    • ArrayDeque是基于可变数组实现的。它在内部使用一个数组来存储元素,并通过调整数组的大小来适应元素的增加和减少。
  2. 性能特点:

    • 随机访问元素的性能较好,因为可以通过索引直接访问数组中的元素,时间复杂度为 O (1)。
    • 在两端添加或删除元素的性能也很高,通常为 O (1) 时间复杂度。但是,在中间位置添加或删除元素可能需要移动大量元素,时间复杂度为 O (n),其中 n 是队列中的元素数量。
  3. 适用场景:

    • 当需要高效地在两端进行添加和删除操作,并且对随机访问有一定需求时,ArrayDeque是一个不错的选择。例如,可以用作栈或队列来处理数据。

二、LinkedList

  1. 底层数据结构:

    • LinkedList是基于双向链表实现的。每个元素都包含指向前一个元素和后一个元素的指针。
  2. 性能特点:

    • 在两端添加或删除元素的性能非常高,时间复杂度为 O (1),因为只需要调整几个指针即可。
    • 随机访问元素的性能较差,需要从头或尾开始遍历链表,时间复杂度为 O (n)。
  3. 适用场景:

    • 当需要频繁地在两端进行添加和删除操作,并且对随机访问的需求较少时,LinkedList很适合。它也可以用作栈、队列或双向链表来处理数据。

三、PriorityQueue:

基于优先级堆实现的无界队列。

元素按照优先级进行排序,优先级高的元素先出队。

总结:

如果需要高效的随机访问以及两端的快速添加和删除操作,可以考虑使用ArrayDeque。如果更注重两端操作的极致性能,并且对随机访问要求不高,可以选择LinkedList。在实际应用中,可以根据具体的需求场景来选择合适的实现类。

(5)Map接口:

存储键值对,每个键都是唯一的。

常见的实现类有HashMap、LinkedHashMap、TreeMap等。

1.HashMap:

基于哈希表实现,存储键值对。

允许一个键为null,多个值为null。

查找、插入和删除操作效率高。

2.LinkedHashMap:

维护了键值对的插入顺序。

同时具有哈希表的高效性和链表的顺序性。

3.TreeMap:

基于红黑树实现,键自动排序。

不允许键重复。

4.WeakHashMap:

其中的键是弱引用。当垃圾回收器回收某个键所对应的对象时,这个键值对会自动从WeakHashMap中被移除。

适用于需要在内存紧张时自动清理不再使用的键值对的场景。

5.IdentityHashMap:

使用引用相等(==)而不是对象相等(equals方法)来判断键和值的相等性。

在某些需要区分不同对象实例的场景下可能会有用。

6.SortedMap:

此接口扩展了Map接口,保证了键的有序性。

提供了一些方法来获取键的范围,例如subMap、headMap和tailMap方法,可以返回一个子映射,包含指定范围内的键值对。

7.NavigableMap:

进一步扩展了SortedMap接口。

提供了更强大的导航方法,如lowerEntry、floorEntry、ceilingEntry和higherEntry,用于查找与给定键最接近的键值对。

8.Hashtable:

是一个古老的实现类,类似于HashMap,但它是线程安全的。

不允许键或值为null。

由于需要同步机制,性能相对较低。

9.ConcurrentHashMap:

线程安全的哈希表实现,允许多个线程同时进行读写操作,而不需要外部同步。

采用了分段锁技术,提高了并发性能。

(6)接口与实现类的关系

接口定义了一组规范和方法,而实现类则具体实现了这些接口,提供了实际的功能。开发者可以根据具体的需求选择合适的接口和实现类。例如,如果需要一个有序的、可重复的集合,可以选择List接口的实现类ArrayList或LinkedList;如果需要一个不重复的集合,可以选择Set接口的实现类。这种设计模式使得代码具有更好的可扩展性和可维护性,因为可以在不修改现有代码的情况下,切换不同的实现类来满足不同的需求。

三、Java 中不同集合类的性能的比较

在 Java 中,不同的集合类在性能方面有各自的特点。以下是对一些常见集合类的性能比较:

(一)、ArrayList 和 LinkedList

  1. 随机访问性能:

    • ArrayList基于动态数组实现,支持快速的随机访问。通过索引访问元素的时间复杂度为 O (1)。
    • LinkedList基于双向链表实现,随机访问需要遍历链表,时间复杂度为 O (n),其中 n 是链表的长度。
  2. 插入和删除性能:

    • 在列表中间位置插入和删除元素时,LinkedList性能更好。因为它只需要调整相邻节点的指针,时间复杂度为 O (1)。而ArrayList需要移动后续元素,时间复杂度为 O (n)。
    • 在列表末尾插入元素时,两者性能相近。

(二)、HashSet、LinkedHashSet 和 TreeSet

  1. 添加和查找性能:

    • HashSet使用哈希表实现,添加和查找元素的时间复杂度通常接近 O (1),在哈希冲突较多时性能会下降。
    • LinkedHashSet在HashSet的基础上维护了元素的插入顺序,性能略低于HashSet。
    • TreeSet基于红黑树实现,添加和查找元素的时间复杂度为 O (log n)。它自动对元素进行排序,适用于需要有序集合的场景。
  2. 内存占用:

    • HashSet和LinkedHashSet通常比TreeSet占用更少的内存,因为红黑树需要额外的空间来维护树的结构。

(三)、HashMap、LinkedHashMap 和 TreeMap

  1. 插入、查找和删除性能:

    • HashMap基于哈希表实现,插入、查找和删除操作的时间复杂度通常接近 O (1)。
    • LinkedHashMap在HashMap的基础上维护了键值对的插入顺序,性能略低于HashMap。
    • TreeMap基于红黑树实现,插入、查找和删除操作的时间复杂度为 O (log n)。它自动对键进行排序,适用于需要有序键值对的场景。
  2. 遍历性能:

    • LinkedHashMap和TreeMap在遍历顺序上有特定的保证,而HashMap的遍历顺序是不确定的。如果需要按照特定顺序遍历集合,LinkedHashMap和TreeMap可能更合适。

(四)、Vector 和 ArrayList

  1. 线程安全性能:
    • Vector是线程安全的,在多线程环境下可以直接使用,但由于需要同步机制,性能相对较低。
    • ArrayList不是线程安全的,在多线程环境下需要额外的同步措施。如果不需要线程安全,ArrayList性能更好。

总体而言,选择集合类时需要根据具体的应用场景来考虑性能需求。如果需要快速的随机访问,可以选择ArrayList或HashMap;如果需要频繁的插入和删除操作,可以考虑LinkedList或LinkedHashMap;如果需要有序集合,可以选择TreeSet或TreeMap。同时,还需要考虑线程安全等其他因素。

四、集合类的工具类

Arrays.asList():

  • 可以将数组转换为List视图。
  • 这个视图是固定大小的,不能进行添加或删除元素的操作,但可以进行修改元素的操作。

Collections.singletonXXX()和Collections.emptyXXX():

  • singletonXXX方法可以创建只包含一个元素的不可变集合,如singletonList、singletonSet等。
  • emptyXXX方法可以创建空的不可变集合,如emptyList、emptySet等。

这些集合类在不同的场景下提供了丰富的选择,以满足各种数据存储和操作的需求。

五、Map和Collection接口联系:

(一)、都是集合框架的一部分

  1. 共同构成集合体系:
    • Map和Collection接口都是 Java 集合框架中的核心接口,它们一起为开发者提供了丰富的数据存储和操作方式。
    • 集合框架旨在提供统一的方式来处理不同类型的数据集合,无论是存储单个元素的集合(如List、Set等)还是存储键值对的映射(如Map)。

(二)、可以相互转换

  1. Map转Collection:

    • 可以通过Map的方法获取其键集(keySet)、值集(values)或键值对集合(entrySet),这些集合都是Collection的子接口的实现。
    • 例如,通过map.keySet()可以得到一个包含Map中所有键的Set集合,这个集合可以进行迭代、添加或删除元素等操作,就像其他普通的Collection集合一样。
  2. Collection转Map:

    • 在某些情况下,可以将一个包含特定类型元素的Collection转换为Map。例如,可以使用 Java 8 的流(Stream)和Collectors.toMap方法将一个包含特定对象的列表转换为一个Map,其中对象的某个属性作为键,对象本身作为值。

(三)、在某些操作上有相似性

  1. 遍历方式:

    • 虽然Map和Collection的内部结构不同,但它们都可以通过迭代器进行遍历。
    • 对于Collection,可以直接使用迭代器遍历集合中的元素。对于Map,可以通过遍历其键集、值集或键值对集合来间接遍历Map中的内容。
  2. 一些通用方法:

    • 部分集合框架的工具类方法可以同时应用于Map和Collection。例如,Collections类中的一些排序、查找等方法可以应用于List等Collection实现类,而在某些情况下,也可以通过将Map的键集或值集转换为Collection后应用这些方法。

总体而言,Map和Collection接口在 Java 集合框架中既有区别又有联系,它们共同为开发者提供了灵活多样的数据处理方式。

相关推荐
小程序设计15 分钟前
本科毕设避坑|大数据 / 单片机物联网 / 网络工程 / PLC / 机械设计选题与落地心得
java·hive·hadoop·单片机
卓怡学长21 分钟前
w206基于SpringBoot的社区团购小程序设计与实现
java·spring boot·spring·intellij-idea
Fruit_Caller34 分钟前
static
开发语言·c++
IT枫斗者枫哥5 小时前
MyBatis一对多分页:LIMIT 20,为什么凑不齐20个订单?
java·数据库
代码方舟5 小时前
Java数据工程:利用天远全网运营商三要素优化线上实名认证合规体验
java·人工智能
BBmmo5 小时前
我的 Java 学习笔记 · 第 7 篇:泛型与通配符
java
独泪了无痕5 小时前
Hutool之RandomUtil:随机数生成的终极利器
java·后端
花开路口5 小时前
深入理解 Java/Kotlin 协变与逆变
java·kotlin
运行时异常6 小时前
【WMS 仓储系统集成 AI Agent 实战】第 7 讲:Vue3 前端工程化——Token 刷新锁、Markdown 渲染踩坑与权限体系
java
她的男孩6 小时前
开放接口限流从 20 改到 200 还是每分钟 20 次:拆完防重放+幂等+限流,我找到 5 个静默失效的坑
java·后端·架构