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接口:

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

子接口有**ListSetQueue**等。

(2)List接口:

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

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

常见的实现类有ArrayListLinkedListVector

1.ArrayList

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

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

2.LinkedList

基于双向链表实现。

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

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

3.Vector

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

4.Stack

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

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

(3)Set接口:

集合中的元素不能重复

不保证 元素的存储顺序

常见的实现类有HashSetLinkedHashSetTreeSet

1.HashSet

使用哈希表实现。

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

查找元素速度快。

2.LinkedHashSet

维护了元素的插入顺序

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

3.TreeSet

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

不允许插入重复元素。

4.EnumSet

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

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

5.CopyOnWriteArraySet

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

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

(4)Queue接口:

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

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

Deque

在 Java 中,Deque是一个双端队列接口 ,它既可以作为队列使用(先进先出,FIFO),也可以作为栈使用(后进先出,LIFO)。ArrayDequeLinkedList是实现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接口:

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

常见的实现类有HashMapLinkedHashMapTreeMap等。

1.HashMap

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

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

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

2.LinkedHashMap

维护了键值对的插入顺序

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

3.TreeMap

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

不允许键重复。

4.WeakHashMap

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

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

5.IdentityHashMap

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

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

6.SortedMap

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

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

7.NavigableMap

进一步扩展了SortedMap接口。

提供了更强大的导航方法,如lowerEntryfloorEntryceilingEntryhigherEntry,用于查找与给定键最接近的键值对。

8.Hashtable

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

不允许键或值为null

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

9.ConcurrentHashMap

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

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

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

接口定义了一组规范和方法,而实现类则具体实现了这些接口,提供了实际的功能。开发者可以根据具体的需求选择合适的接口和实现类。例如,如果需要一个有序的、可重复的集合,可以选择List接口的实现类ArrayListLinkedList;如果需要一个不重复的集合,可以选择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),在哈希冲突较多时性能会下降。
    • LinkedHashSetHashSet的基础上维护了元素的插入顺序,性能略低于HashSet
    • TreeSet基于红黑树实现,添加和查找元素的时间复杂度为 O (log n)。它自动对元素进行排序,适用于需要有序集合的场景。
  2. 内存占用:

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

(三)、HashMap、LinkedHashMap 和 TreeMap

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

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

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

(四)、Vector 和 ArrayList

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

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

四、集合类的工具类

Arrays.asList()

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

Collections.singletonXXX()Collections.emptyXXX()

  • singletonXXX方法可以创建只包含一个元素的不可变集合,如singletonListsingletonSet等。
  • emptyXXX方法可以创建空的不可变集合,如emptyListemptySet等。

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

五、MapCollection接口联系:

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

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

(二)、可以相互转换

  1. MapCollection

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

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

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

  1. 遍历方式:

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

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

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

相关推荐
今天吃饺子4 分钟前
2024年SCI一区最新改进优化算法——四参数自适应生长优化器,MATLAB代码免费获取...
开发语言·算法·matlab
努力进修9 分钟前
“探索Java List的无限可能:从基础到高级应用“
java·开发语言·list
politeboy9 分钟前
k8s启动springboot容器的时候,显示找不到application.yml文件
java·spring boot·kubernetes
Daniel 大东1 小时前
BugJson因为json格式问题OOM怎么办
java·安全
Ajiang28247353042 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空2 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10225 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸6 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象7 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了7 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring