Map
TreeMap
、HashMap
、LinkedHashMap
、Hashtable
、WeakHashMap
概述:
Map
存储键值对,键不可重复Map
下有SortedMap
接口、AbsractMap
抽象类Map
接口提供的通用方法get(Object key)
:返回给定键的值getOrDefault(Object key, V defaultValue)
:返回给定键的值,若键不存在,则返回默认值put(K key, V value)
:将指定值与指定键关联,若键不存在,则添加键值对putAll(Map<? extends K,? extends V> map)
:将多个键值对关联remove(Object key)
:删除键值对clear()
:删除所有键值对containsKey(Object key)
:判断是否包括给定键containsValue(Object value)
:如果一个或多个键被映射到给定值,则返回true
replace(K key, V oldValue, V newValue)
:当给定键映射到给定值时,替换值size()
:返回键值对总数isEmpty()
:判断是否为空equals(Object o)
:判断是否与给定对象相等
TreeMap
:
-
TreeMap
存储有序的键值对 -
数组 + 红黑树,不是线程安全的
-
初始化并自定义排序规则
TreeMap<K, V> map = new TreeMap<>( new Comparator<K>() { @Override public int compare(K a, K b) { // 若 a 应排在 b 前则返回负数 return b - a; // 降序排序 // return a - b; // 升序排序 } } );
- 初始化
TreeMap
时调用构造方法public TreeMap(Comparator<? super E> comparator)
- 构造方法的输入参数是
Comparator
比较器,其中Comparator
是接口 - 通过匿名类实现接口并重写
compare
方法 (菜鸟教程:Java 匿名类)
- 初始化
-
遍历方法
for (Map.Entry<K, V> entry : map.entrySet()) { entry.getKey(); entry.getValue(); entry.setValue(); ... }
-
常用方法
ceilingEntry(K key)
、ceilingKey(K key)
:返回大于等于给定键的键值对 / 键,若无则返回null
floorEntry(K key)
、floorKey(K key)
:返回小于等于给定键的键值对 / 键,若无则返回null
higherEntry(K key)
、higherKey(K key)
:返回严格大于给定键的键值对 / 键,若无则返回null
lowerEntry(K key)
、lowerKey(K key)
:返回严格小于给定键的键值对 / 键,若无则返回null
firstEntry()
、firstKey()
:返回第一个键值对 / 键lastEntry()
、lastKey()
:返回最后一个键值对 / 键pollFirstEntry()
、pollLastEntry()
:返回并删除第一个 / 最后一个键值对headMap(K toKey, boolean inclusive)
:返回小于给定键的键值对的集合tailMap(K fromKey, boolean inclusive)
:返回大于给定键的键值对的集合subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
:返回给定区间的键值对的集合descendingMap()
:返回逆序的键值对映射
HashMap
:
HashMap
存储无序的键值对,遍历时不保证顺序- 数组 + 链表 + 红黑树,不是线程安全的
- 初始化
HashMap<K, V> map = new HashMap<>();
LinkedHashMap
:
-
LinkedHashMap
存储无序的键值对,在HashMap
的基础上添加双向链表,可按插入 / 访问顺序遍历 -
数组 + 双向链表 + 红黑树,不是线程安全的
-
初始化
LinkedHashMap<K, V> map = new LinkedHashMap<>(int initialCapacity, float loadFactor, boolean accessOrder);
initialCapacity
是初始数组长度,默认16
loadFactor
是负载因子,当键值对数量与数组长度之比超过负载因子时需要扩容,默认0.75f
accessOrder
是遍历顺序,false
基于插入顺序 (默认),true
基于访问顺序
-
常用方法
removeEldestEntry(Map.Entry<K,V> eldest)
:在插入键值对后,调用removeEldestEntry
判断是否需要删除最旧键值对;removeEldestEntry
永远返回false
,即永远扩容数组而不删除键值对,可根据需求重写该方法
-
初始化并重写
removeEldestEntry
LinkedHashMap<Integer, Integer> lru = new LinkedHashMap<Integer, Integer>(capacity, 1f, true) { @Override protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) { return size() > capacity; } };
Hashtable
:
Hashtable
存储无序的键值对- 数组 + 链表,是线程安全的 (与
HashMap
的不同点) - 性能差,被淘汰
WeakHashMap
:
- 待补充
Collection
概述:
Collection
存储元素本身Collection
下有Set
接口、List
接口、Queue
接口Collection
接口提供的通用方法add(E e)
:添加元素addAll(Collection<? extends E> c)
:添加多个元素remove(Object o)
:删除元素removeAll(Collection<?> c)
:删除多个元素clear()
:删除所有元素contains(Object o)
:判断是否包括给定元素containsAll(Collection<?> c)
:判断是否包括给定的多个元素size()
:返回元素总数isEmpty()
:判断是否为空equals(Object o)
:判断是否与给定对象相等toArray()
:转换成数组
Set
概述:
Set
存储不重复元素的集合Set
下有SortedSet
接口、AbsractSet
抽象类
TreeSet
:
-
TreeSet
存储有序的不重复元素的集合 -
数组 + 红黑树,不是线程安全的
-
初始化并自定义排序规则
TreeSet<E> set = new TreeSet<>( new Comparator<E>() { @Override public int compare(E a, E b) { // 若 a 应排在 b 前则返回负数 return b - a; // 降序排序 // return a - b; // 升序排序 } } );
-
常用方法
ceiling(E e)
:返回大于等于给定元素的元素,若无则返回null
floor(E e)
:返回小于等于给定元素的元素,若无则返回null
higher(E e)
:返回严格大于给定元素的元素,若无则返回null
lower(E e)
:返回严格小于给定元素的元素,若无则返回null
first()
:返回第一个元素last()
:返回最后一个元素pollFirst()
:返回并删除第一个元素pollLast()
:返回并删除最后一个元素headSet(E toElement, boolean inclusive)
:返回小于给定元素的元素的集合tailSet(E fromElement, boolean inclusive)
:返回大于给定元素的元素的集合subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)
:返回给定区间的元素的集合descendingSet()
:返回逆序的元素的集合
HashSet
:
HashSet
存储无序的不重复元素的集合,遍历时不保证顺序- 数组 + 链表 + 红黑树 (采用
HashMap
实现),不是线程安全的 - 初始化
HashSet<E> set = new HashSet<>();
LinkedHashSet
:
LinkedHashSet
存储无序的不重复元素的集合,在HashSet
的基础上添加双向链表,可按插入顺序遍历 (不能按访问顺序遍历)- 数组 + 双向链表 + 红黑树 (采用
LinkedHashMap
实现),不是线程安全的 - 初始化
LinkedHashSet<E> set = new LinkedHashSet<>();
List
概述:
List
存储可重复元素的列表List
下有AbstractList
接口List
接口提供的通用方法add(int index, E element)
:在给定位置插入元素 (插入后get(index)
得到的即是该元素)get(int index)
:返回给定位置的元素set(int index, E element)
:修改给定位置的元素indexOf(Object o)
:返回第一次出现给定元素的索引lastIndexOf(Object o)
:返回最后一次出现给定元素的索引subList(int fromIndex, int toIndex)
:返回给定区间的元素的集合
ArrayList
:
ArrayList
存储可重复元素的列表,查找快、增删慢- 数组,不是线程安全的
- 初始化
ArrayList<E> list = new ArrayList<>();
LinkedList
:
LinkedList
存储可重复元素的列表,查找慢、增删快- 双向链表,不是线程安全的
- 初始化
LinkedList<E> list = new LinkedList<>();
- 常用方法
addFirst(E e)
、offerFirst(E e)
:在头部插入元素addLast(E e)
、offerLast(E e)
、add(E e)
、offer(E e)
、push(E e)
:在尾部插入元素getFirst()
、peekFirst()
、element()
、peek()
:返回第一个元素getLast()
、peekLast()
:返回最后一个元素pollFirst()
、removeFirst()
、poll()
:返回并删除第一个元素pollLast()
、removeLast()
、pop()
:返回并删除最后一个元素removeFirstOccurrence(Object o)
:删除第一次出现的给定元素removeLastOccurrence(Object o)
:删除最后一次出现的给定元素- 说明
- 栈相关操作:
push
、pop
- 队列相关操作:
offer
、peek
、poll
(LinkedList
实现了Deque
接口)
- 栈相关操作:
Vector
:
- 数组,是线程安全的
- 性能差,被淘汰
Stack
:
- 数组,是线程安全的
- 性能差,被淘汰
Queue
概述:
-
Queue
存储可重复元素的队列,只能在队头队尾操作 -
Queue
下有Deque
接口 (双端队列)、AbstractQueue
抽象类 (单向队列) -
Queue
接口提供的两套增删查方法add
、remove
、get
:方法失败时抛出异常offer
、poll
、peek
:方法失败时返回默认值false
或null
-
Deque
接口在Queue
接口的两套增删方法上添加了First
和Last
的后缀addFirst
、addLast
...offerFirst
、offerLast
...- 此外
Deque
接口中有模仿栈的push
和pop
方法
ArrayDeque
:
ArrayDeque
存储可重复元素的队列,只能在队头队尾操作,是双端队列- 数组 (与
LinkedList
的不同点),不是线程安全的 - 初始化
ArrayDeque<E> queue = new ArrayDeque<>();
PriorityQueue
:
-
PriorityQueue
存储可重复元素的队列,只能在队头队尾操作,保证元素按指定顺序排列 -
堆 (数组),不是线程安全的
-
初始化初始化并自定义排序规则
PriorityQueue<E> queue = new PriorityQueue<>( new Comparator<E>() { @Override public int compare(E a, E b) { // 若 a 应排在 b 前则返回负数 return b - a; // 降序排序 // return a - b; // 升序排序 } } );
工具
排序:
Arrays.sort()
、Collections.sort()
-
Arrays.sort(T[] a, Comparator<? super T> c)
针对基本数据类型和引用对象类型的数组排序 -
Collections.sort(List<T> list, Comparator<? super T> c)
针对集合框架排序 -
当使用
Comparator
时,T
不能是int
,而应是Integer
,若要将int
转换成Integer
需要 \(O(n)\) 的遍历 -
自定义排序规则
// 匿名类写法 Integer [] nums = new Integer[] {1, 4, 5, 3, 2}; Arrays.sort(nums, new Comparator<Integer>() { // 若 a 应排在 b 前则返回负数 @Override public int compare(Integer a, Integer b) { return a - b; // 升序排序 // return b - a; // 降序排序 } }); // lambda 写法 Integer [] nums = new Integer[] {1, 4, 5, 3, 2}; Arrays.sort(nums, (a, b) -> a - b); // 或 Arrays.sort(nums, (Integer a, Integer b) -> { return a - b; });
遍历:
Iterator
、Iterable
、ListIterator
-
Iterator
是供集合操作内部对象的迭代器,可以遍历、移除对象,只能单向移动hasNext()
:判断集合中是否存在下一个对象next()
:返回集合中的下一个对象,并将访问指针移动一位remove()
:删除集合中下次调用next()
方法返回的对象
List<Integer> list = new ArrayList<>(); Iterator iter = list.iterator(); while (iter.hasNext()) { Integer num = iter.next(); System.out.println(num); }
-
Iterable
是对Iterator
的封装,在 JDK 1.8 时,实现了Iterable
接口的集合可以使用增强 for 循环遍历集合对象List<Integer> list = new ArrayList<>(); for (Integer num : list) { System.out.println(num); }
-
ListIterator
继承Iterator
接口,在遍历集合时可以从任意索引下标开始遍历,且支持双向遍历hasNext()
、next()
、remove()
hasPrevious()
、previous()
nextIndex()
、previousIndex()
set(E e)
:替换最近一次next()
方法或previous()
方法返回的对象add(E e)
:在最近一次next()
方法或previous()
方法返回的对象后添加元素
List<Integer> list = new ArrayList<>(); ListIterator<Integer> listIter1 = list.listIterator(); ListIterator<Integer> listIter2 = list.listIterator(5);