java 容器类动态,Java 容器类型复习笔记

7980ef8d16531c9adc2ca05add829da6.png 最近抽空把 java.lang 下面常用的那些容器类型(数据结构)复习了一下,这些东西是基础,平时使用的时候也可以很容易查得到,有些方法大概知道,但是总是弄混,如果可以记住那些重要方法,并且能够熟练使用的话,还是可以让编码过程变得容易很多。另外一个是实现机制,对于常用数据结构的实现机制,应该说是必须要熟知的。

另外,并发容器我之前整理过,放在这篇文章里。

Queue

add 和 offer 的区别在于达到上限时 add 抛出异常,offer 返回 false;

remove 和 poll 的区别在于,队列为空时前者抛出异常,后者返回空;

element 和 peek 都返回队列头部元素,但是前者失败不抛出异常,后者返回空。

boolean add(E e);

boolean offer(E e);

E remove();

E poll();

E element();

E peek();

PriorityQueue,内部实现是一个 Object[] queue 承载的堆。

Deque,双端队列(double-ended queue),在 Queue 基础上,增加了这样几个方法:

void addFirst(E e);

void addLast(E e);

boolean offerFirst(E e);

boolean offerLast(E e);

E removeFirst();

E removeLast();

E pollFirst();

E pollLast();

E getFirst();

E getLast();

E peekFirst();

E peekLast();

boolean removeFirstOccurrence(Object o);

boolean removeLastOccurrence(Object o);

ArrayDequeue:数组实现,扩容策略是容量翻倍。

List

boolean add(E e);

boolean remove(Object o);

E get(int index);

E set(int index, E element);

void add(int index, E element);

E remove(int index);

ArrayList,扩容策略是 (oldCapacity * 3)/2 + 1。

LinkedList,它除了实现自 List 接口外,还实现了 Deque 接口。

Vector,实现自 List 接口,内部实现是个数组,线程安全,扩容策略是 (capacityIncrement > 0) ? (oldCapacity + capacityIncrement) : (oldCapacity * 2)。

Stack 是 Vector 的子类,增加了一些栈的方法:

E push(E item)

E pop()

E peek()

boolean empty()

Map

boolean containsKey(Object key);

boolean containsValue(Object value);

V get(Object key);

V put(K key, V value);

V remove(Object key);

Set keySet();

Collection values();

Set> entrySet();

SotedMap 接口,key 是有序的 map:

SortedMap subMap(K paramK1, K paramK2);

SortedMap headMap(K paramK);

SortedMap tailMap(K paramK);

K firstKey();

K lastKey();

子接口 NavigableMap,提供了一些根据某个 key 寻找它前面或者后面的 key 的方法。其中 floorKey/celingKey 表示的关系是小于等于/大于等于,lower/higher 表示的关系是严格的小于/大于:

Map.Entry floorEntry(K key)

K floorKey(K key)

Map.Entry ceilingEntry(K key)

K ceilingKey(K key)

Map.Entry lowerEntry(K key)

K lowerKey(K key)

Map.Entry higherEntry(K key)

K higherKey(K key)

TreeMap 是 NavigableMap 的直接实现子类,内部实现是一个红黑树。

EnumMap,结构是, V>,内部是通过一个 K[] keyUniverse 和一个 Object[] vals 来实现的。

HashMap,内部是数组+链表实现的,达到 threshold = capacity * loadFactor 时,扩容策略为:numKeysToBeAdded / loadFactor + 1。

HashTable,实现自 Dictionary 和 Map,方法都是线程安全的。HashTable 的 put 方法,value 不可以为空,这是它和 HashMap 的一个不同;再有二者找桶的 hash 方法不同;最后则是 threshold 计算逻辑相同,但它的扩容策略不同:oldCapacity * 2 + 1。HashTable、HashMap 和 HashSet 经常被放到一起比较。

Properties,是 HashTable 的子类,方法线程安全。

IdentityHashMap,比较 key 不是使用 equals 来比较,而是使用 “==” 来比较,只要地址不等(即不是同一个对象)即可共存,也就是说,key 是可以重复的。

LinkedHashMap,在 HashMap 的基础上,又单独维护了一个双向循环链表。有一个重要参数是 accessOrder,accessOrder 为 true 时,每次调用 get 方法访问行为发生后,会把最近访问的对象移动到头部,而超出容量移除对象时,是从尾部开始的,利用它并且覆写 boolean removeEldestEntry 方法可以实现一个 LRU 的队列。

WeakHashMap,但是 key 是 weak 引用,在不被使用时自动清除,扩容策略:tab.length * 2。原理上看:Entry extends WeakReference implements Map.Entry,因此 entry 是弱引用的实现类,关键方法是 expungeStaleEntries,它在对这个 map 各种操作的时候都会被调用到,而这个方法里面也是靠监听 key 的 ReferenceQueue 这个队列的状态来确定是否真的没有对象引用了。

Set

boolean contains(Object o);

boolean add(E e);

boolean remove(Object o);

SortedSet,接口方法和 SortedMap 类似:

SortedSet subSet(E fromElement, E toElement);

SortedSet headSet(E toElement);

SortedSet tailSet(E fromElement);

E first();

E last();

相应地,NavigableSet 和 NavigableMap 类似,方法就不列出了。

TreeSet 则和 TreeMap 类似,其实内部实现就是一个 TreeMap。

HashSet,尤其注意的是,有两种实现,当构造方法参数小于 3 个时,内部使用 HashMap,否则,使用 LinkedHashMap。

RegularEnumSet 和 JumboEnumSet,前者是普通的枚举 set(用位移来表示各种组合的可能,达到空间占用最小,最大不能超过 64 个枚举值),后者适合数量较大的枚举 set(老老实实地使用对象数组)。

LinkedHashSet,其实和 LinkedHashMap 是一个东西。

BitSet,叫 set 但是没有实现 set 的接口。用比特位来存放某个数是否存在,比如仅仅一个 long,64 位,就可以存放 0~63 的数,内部实际的数据类型是 long[]。

void flip(int bitIndex);

void flip(int fromIndex, int toIndex);

void set(int bitIndex);

void set(int fromIndex, int toIndex, boolean value);

void clear(int bitIndex);

int length();

int size();

其中 size 方法返回实际使用了的比特位数目;length 方法返回逻辑意义上的长度(比如表示的数里面最大是 80,那么加上 0,它的逻辑意义上的长度就是 81)。

扩容策略:Math.max(2 * words.length, wordsRequired)。

Dictionary

Enumeration keys();

Enumeration elements();

V get(Object key);

V put(K key, V value);

V remove(Object key);

已经被废弃了,用 Map 来实现相同功能。

最后这张图来自这个网站,对于从宏观上把握这些容器类型实在是太有帮助了:

40498afe0658f29661aebdb2434de9e8.png

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

×Scan to share with WeChat

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值