Java 集合
- 集合关键看两个接口,Collection和Map,Collection用于存储单个元素,Map用于存储key-value。Collection下面又有三个主要的子接口:List、Set 、 Queue。
- Set:存储元素不可重复
- HashSet:无序唯一(底层用的HashMap)
- LinkedHashSet:通过LinkedHashMap实现的
- TreeSet:有序且唯一(红黑树)
- List:存储元素可重复且有序
- ArrayList:线程不安全,内存空间占用在于会预留空间(扩展的时候默认x1.5)
- 扩容机制:默认初始capacity=10,但是只有真正加入元素的时候才会创建,后续当元素达到capacity的时候,扩容为原来的1.5倍(调用 Arrays.copyOf方法)。为了避免多次扩容,在插入大量元素之前,先调用ensureCapacity提前扩容。
- Vector:线程安全(synchronized关键字,Stack继承Vector)
- LinkedList:双向链表,内存空间占用在于会预留前后指针空间
- ArrayList:线程不安全,内存空间占用在于会预留空间(扩展的时候默认x1.5)
- Queue:FIFO
- PriorityQueue:优先级队列,默认小顶堆(重要!)
- 利用二叉堆 + 可变长数组
- O(logn)时间复杂度
- 非线程安全,不支持null和non-comparable对象存储
- 支持接收Comparator自定义优先级
- ArrayDeque:可扩容双向数组
- PriorityQueue:优先级队列,默认小顶堆(重要!)
- Map:key无序不可重复,value无序可重复可为null(无序指的是存储的时候按照HashCode决定而不是数组索引顺序,不可重复是由equals方法保证)
- HashMap:数组+链表(jdk1.8之前),jdk1.8之后引入红黑树:1. 判断数组长度是否小于64,小于则先进行数组扩容。2.当长度大于等于64之后,判断链表长度是否大于阈值(默认8)则转为红黑树提高搜索效率
- LinkedHashMap:在HashMap基础上加了一个双向链表,让结构可以保持键值对插入顺序,并且保证访问顺序
- TreeMap:红黑树(要求元素支持排序)
关于Map相关知识点,可以看我另一篇文章 -> 简单回顾Map看这一篇就够了
Queue和Deque
- 补充一下这俩货,老是忘记他们的方法,可能也是用的少
- 他们的方法可以根据操作失败是否抛出异常分为两类
Queue | 抛异常 | 返回特殊值 |
---|---|---|
插入队尾 | add(E e) | offer(E e) (满了返回 false) |
删除队首 | remove() | poll() (空了返回null) |
查询队首元素 | element() | peek() (空了返回null) |
Deque | 抛异常 | 返回特殊值 |
---|---|---|
插入队首 | addFrist(E e) | offerFrist(E e) (满了返回 false) |
插入队尾 | addLast(E e) | offerLast(E e) (满了返回 false) |
删除队首 | removeFirst() | pollFirst() (空了返回null) |
删除队尾 | removeLast() | pollLast() (空了返回null) |
查询队首元素 | getFirst() | peekFirst() (空了返回null) |
查询队尾元素 | getLast() | peekLast() (空了返回null) |
BlockingQueue 阻塞队列
- 阻塞队列常用于生产-消费者模型
- 当队列元素为空的时候,消费者take元素会被阻塞
- 当队列元素满时,生产者put元素会被阻塞
常见的阻塞队列实现
- ArrayBlockingQueue:使用数组实现的有界队列,需要指定大小,支持公平和非公平锁(没有锁分离,生产和消费者使用的是同一个锁)
- LinkedBlockingQueue:单向链表实现的有界队列,不制定大小默认为Integer.MAX_VALUE.仅支持非公平的锁访问。(锁分离,生产用putLock,消费是takeLock
,防止生产和消费锁争夺) - PriorityBlockingQueue:支持优先级排序的无界阻塞队列。元素必须实现Comparable接口和构造函数中传入Comparator对象,不支持插入null。
…