Java集合知识梳理

本文主要梳理了Java集合框架,包括Collection接口的List、Set、Queue子接口及其具体实现类如ArrayList、LinkedList、HashSet、TreeSet等的特点和应用场景,以及Map接口的HashMap、HashTable、TreeMap和LinkedHashMap的差异和使用注意事项。重点讨论了各集合类的存储结构、增删查改性能和线程安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

提示:Java集合的知识很零散,但是理解起来也不是很难,只要弄清各个接口和实现的关系,以及各种集合的应用场景,还是能自成系统的,写这篇文章也是为了给自己梳理一下,看自己掌握了哪些内容,还有哪些没有掌握。


提示:以下是本篇文章正文内容,下面案例可供参考

一、集合

集合的概览如下图所示:

集合

从图上可以看出集合有两大接口:Collection和Map

  1. Collection存放的是单个对象;
  2. Map存放的是key-value键值对;

他们都实现了Iterator接口,这是一个迭代器接口,表明所有的集合和Map都有迭代器这个属性,利用迭代器进行遍历查询。

二、Collection

Collection有 List,set,Queue接口。

  • List底层特点是有序,元素可以重复;
  • set特点是无序,元素不能重复;
  • Queue是元素从一端进,从另一端出的队列;

1.List

List的具体实现类包括ArrayList,LinkedList,和Vector

1.1 ArrayList

  • 底层采用数组存储元素,与数组不同的是空间不足时能自动扩充存储空间,每次扩充空间后是原来空间的1.5倍;
  • 带有索引,随机访问速度快,适合遍历访问;
  • 当插入和删除中间位置的元素时,需要移动其后所有的元素的位置,因此增删的效率不高;
  • 线程不安全;

1.2 LinkedList

  • 底层采用链表存储元素,插入和删除的效率更高,适合插入和删除;
  • 不适合随机访问;

1.2 Vector

  • 和ArrayList相同底层也是采用数组存储元素,不同的是Vec是线程安全的,每个时刻只允许一个线程对其进行操作,因此其效率不高;
  • 另一个与ArrayList不同点是其空间扩充时,扩充后的空间大小是原来的2倍。

2.Set

Set接口的实现由HashSet,LinkedHashSet,TreeSet;

2.1 HashSet

  • 底层采用HashMap存储元素,存储元素的顺序不按照元素存入时的顺序;
  • 基本操作的时间复杂度都是O(1),存取速度快;
  • 保证元素不重复是通过HashCode方法和equals方法实现的,hashCode决定元素存储的位置,equals方法决定元素是否重复;

2.2 LinkedHashSet

  • 底层采用LinkedHashMap存储元素,使得元素按照存入时的顺序有序存储元素,最大的特点就是有序;
  • 由于底层采用链表存储元素,因此迭代访问的效率比较高,插入的性能低;(思考)

2.3 TreeSet

  • 采用红黑树对新增加的对象按照指定的顺序进行排序,可以使用自然排序和自定义比较器来排序;
  • 自定义类使用TreeSet来存储必须实现Comparable接口,并且重写compareTo()函数;
  • 缺点是查询速度没有HashSet快;

3.Queue

Queue用于模拟"队列"这种数据结构(先进先出 FIFO)。队列的头部保存着队列中存放时间最长的元素,队列的尾部保存着队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素,队列不允许随机访问队列中的元素。

Queue的实现类有LinkedList,ArrayDqueue,PriorityQueue。其中LinkedList,ArrayDqueue又继承自Dqueue,Deque接口代表一个"双端队列",双端队列可以同时从两端来添加、删除元素,因此Deque的实现类既可以当成队列使用、也可以当成栈使用

LinkedList和ArrayDqueue都能实现队列,他们的区别:

  1. ArrayDqueue是一个可扩容的数组,LinkedList底层是链表结构;
  2. ArrayDqueue不能存储null值,但是LinkedList可以;
  3. ArrayDqueue在操作尾端的增删操作时更加高效;
  4. ArrayDqueue在内存使用方面更加高效;

综上所述,一般选择使用ArrayDqueue,但是ArrayDqueue实在java6之后才出现的,java6之前不能使用ArrayDqueue。

3.1 LinkedList

基于链表的双端队列,不适合随机访问,适合增删。

3.2 ArrayDqueue

是一个基于数组的双端队列,和ArrayList类似,它们的底层都采用一个动态的、可重分配的Object[]数组来存储集合元素,当集合元素超出该数组的容量时,系统会在底层重新分配一个Object[]数组来存储集合元素

3.3 PriorityQueue

PriorityQueue并不是一个比较标准的队列实现,PriorityQueue保存队列元素的顺序并不是按照加入队列的顺序,而是按照队列元素的大小进行重新排序


三、Map

1.HashMap

  • 需要重写HashCode和equals方法
  • key不允许有重复,可以允许key有一个null值;
  • 线程不安全
  • 存取速度快,存储的顺序不确定
  • 基本操作:put remove put get
  • 如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来

2.HashTable

  • 与HashMap的区别是线程安全
  • 不允许key为null

3.TreeMap

  • 可以实现排序,一种是自然排序,一种是定制排序,具体取决于使用的构造方法
  • 基于红黑树(Red-Black tree)实现,每一个 key-value 节点作为红黑树的一个节点。
  • 如果使用自定义的类来作为 TreeMap 中的 key 值,且想让 TreeMap 能够良好的工作,则必须重写自定义类中的equals()方法,TreeMap 中判断相等的标准是:两个 key 通过equals()方法返回为 true,并且通过compareTo()方法比较应该返回为 0。

提示:复习时可参考[这篇文章],多看看,加深理解(https://www.huaweicloud.com/articles/8613c43982c7e6c6e3e6d35ccd613ecc.html)

4.LinkedHashMap

  • LinkedHashMap 是 HashMap 的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用 LinkedHashMap
  • 底层为双端链表,由于 LinkedHashMap 需要维护元素的插入顺序,因此性能略低于 HashMap 的性能,但在迭代访问 Map 里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。

总结

提示:这里对文章进行总结:
该部分内容需要不停的扩充,需要经常复习,真正掌握在自己的脑海中,这样无论在面试中还是在日常的工作中,都是有好处的,要不停的看关于这方面的知识,看到自己没有掌握的知识,及时记忆和理解,并且用自己的话总结出来,以便后面复习和复盘。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值