1.Queue类
Queue 接口 | 抛出异常 | 返回特殊值 |
---|---|---|
插入队尾 | add(E e) | offer(E e) |
删除队首 | remove() | poll() |
查询队首元素 | element() | peek() |
1.1.Deque类
Deque 接口 | 抛出异常 | 返回特殊值 |
---|---|---|
插入队首 | addFirst(E e) | offerFirst(E e) |
插入队尾 | addLast(E e) | offerLast(E e) |
删除队首 | removeFirst() | pollFirst() |
删除队尾 | removeLast() | pollLast() |
查询队首元素 | getFirst() | peekFirst() |
查询队尾元素 | getLast() | peekLast() |
Deque 还提供有 push() 和 pop() 等其他方法,可用于模拟栈。
1.2.PriorityQueue
PriorityQueue 利用了二叉堆的数据结构来实现的,底层使用可变长的数组来存储数据.
PriorityQueue 通过堆元素的上浮和下沉,实现了在 O(logn) 的时间复杂度内插入元素和删除堆顶元素。
PriorityQueue 是非线程安全的,且不支持存储 NULL 和 non-comparable 的对象。
PriorityQueue 默认是小顶堆,但可以接收一个 Comparator 作为构造参数,从而来自定义元素优先级的先后。
PriorityQueue 在面试中可能更多的会出现在手撕算法的时候,典型例题包括堆排序、求第 K 大的数、带权图的遍历等,所以需要会熟练使用才行。
1.2.1什么是 BlockingQueue(阻塞队列)?(了解)
BlockingQueue (阻塞队列)是一个接口,继承自 Queue。BlockingQueue阻塞的原因是其支持当队列没有元素时一直阻塞,直到有元素;还支持如果队列已满,一直等到队列可以放入新元素时再放入
1.3.DelayQueue
1.4. ArrayDeque
可扩容双向数组。基本可以替代LinkedList,且性能更好。
2.Set类
2.1.Set
-
void add(Object k)
添加k -
boolean contains(Object k)
如果map中包含k,则返回true。
2.2.HashSet
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
HashSet 允许有 null 值。
HashSet 是无序的,即不会记录插入的顺序。
HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
HashSet 实现了 Set 接口。
import java.util.HashSet; // 引入 HashSet 类
//实例化途径一
HashSet<String> sites = new HashSet<String>();
//实例化途径二
HashSet<String> sites = new HashSet<>();
//实例化途径三,注意这样实例化需要同时引入Set包
Set<String> sites = new HashSet();
2.3.LinkedHashSet
LinkedHashSet基于HashSet 实现,内部由LinkedHashMap实现。
2.4.TreeSet
数据有序,唯一。底层为红黑树。
2.5 HashSet + LinkedHashSet + TreeSet 三者区别
HashSet 用于不需要保证元素插入和取出顺序的场景,LinkedHashSet 用于保证元素的插入和取出顺序满足 FIFO 的场景,TreeSet 用于支持对元素自定义排序规则的场景。
3.开发时注意事项
判断所有集合内部的元素是否为空,使用 isEmpty() 方法,而不是 size()==0 的方式。
不要在 for-each 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。
可以利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的 contains() 进行遍历去重或者判断包含操作。