專欄原創出處:github-源筆記文件 ,github-源碼 ,歡迎 Star,轉載請附上原文出處鏈接和本聲明。
Java 核心知識專欄系列筆記,系統性學習可訪問個人覆盤筆記-技術博客 Java 核心知識
1. Iterable 接口是幹什麼用的?
Java 中的 Iterable 接口表示它的實現類是支持 for-each 循環,也就是可迭代的,只有這麼一個簡單的功能。這也就是能用 for (Object o : iterable)
的原因。
public interface Iterable<T> {
Iterator<T> iterator(); // 返回一個迭代器
}
迭代器主要源碼:
public interface Iterator<E> {
boolean hasNext(); // 判斷是否由下一個元素
E next(); // 返回下一個元素
default void remove() { // 移除當前元素
throw new UnsupportedOperationException("remove");
}
}
那麼它是怎麼實現 for-each 循環的呢?
通過一段字節碼我們分析。
/*
字節碼:
stack=1, locals=4, args_size=2
0: aload_1
1: invokeinterface #2, 1 // 調用 iterator 返回迭代器,InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
6: astore_2 // 將 iterator 返回值存儲到局部變量表
7: aload_2 // 將 iterator 壓入棧中
8: invokeinterface #3, 1 // 調用 hasNext 方法 InterfaceMethod java/util/Iterator.hasNext:()Z
13: ifeq 26 // 如果返回 true ,否則調到字節碼 26 返回
16: aload_2 // 將 iterator 壓入棧中
17: invokeinterface #4, 1 // 調用 next 方法返回 object InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
22: astore_3 // 將 object 存儲到局部變量
23: goto 7 // 繼續循環
26: return
LocalVariableTable:
Start Length Slot Name Signature
0 27 0 this Lio/gourd/java/core/collection/IterableExample;
0 27 1 iterable Ljava/lang/Iterable;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 27 1 iterable Ljava/lang/Iterable<Ljava/lang/Object;>;
*/
public void forEach(Iterable<Object> iterable) {
for (Object o : iterable) {
// code ...
}
}
理解了爲什麼能用 for-each 後,那麼爲什麼有些集合還可以用 for 通過下標隨機訪問呢?具體分析可參考另一篇文章 Java for、foreach 循環底層實現原理,以及如何判斷集合支持 foreach 循環 ,此處不做重複。
2. 集合體系接口關係概覽
Iterable 接口與 Map 接口在 Java 體系中佔主要地位,基本上所有的數據結構都是基於這個兩個接口,一個是線性可迭代的一個是哈希表。
JDK 中的繼承 Iterable 的主要接口
通過上圖看出,Collection
接口作爲集合體系的父接口,Map
作爲哈希表體系的接口。
先看最主要的集合 Collection 源碼提供方法:
public interface Collection<E> extends Iterable<E> {
int size(); // 集合大小
boolean isEmpty(); // 是否爲空
boolean contains(Object o); // 是否包含某個元素
Iterator<E> iterator(); // 返回迭代器
Object[] toArray(); // 返回 Object 數組
<T> T[] toArray(T[] a); // 返回指定泛型的數組
boolean add(E e); // 添加一個元素,返回是否添加成功
boolean remove(Object o); // 移除一個元素,返回是否添加成功
boolean containsAll(Collection<?> c); // 是否包含另一個集合
boolean addAll(Collection<? extends E> c); // 將另一個集合添加到當前集合
boolean removeAll(Collection<?> c); // 移除當前集合的元素,返回集合是否被修改過
default boolean removeIf(Predicate<? super E> filter); // 根據添加移除元素
boolean retainAll(Collection<?> c); // 僅保留存在於給定集合的元素,返回集合是否被修改過
void clear(); // 清空集合
}
2.1 Queue
特徵:先進先出,尾部添加頭部移除(尾進頭出)
-
Deque 雙端隊列,支持兩端插入和移除的隊列
-
BlockingQueue 阻塞隊列,容量是已知的,不像非阻塞隊列可以動態擴容。
-
BlockingDeque 在阻塞隊列基礎上擴展了雙端隊列的特性
-
TransferQueue 在阻塞隊列基礎擴展了生產者等待消費者消費的機制
2.2 List
特徵:有序的集合,可通過下標操作集合內的元素,支持隨機訪問。
2.3 Set
特徵:不包含重複元素的集合,不支持隨機訪問,大多數實現類底層使用了 Map<K,NULL> 結構實現。
-
SortedSet 有序的不重複集合
-
NavigableSet 再 SortedSet 基礎上擴展了導航相關的方法,比如可以返回此集合中小於或等於給定元素的最大元素
2.4 Map
特徵:哈希表,K-V 映射,K 是不重複的。
-
SortedMap 有序的哈希表
-
ConcurrentMap 支持併發的哈希表
-
NavigableMap 在 SortedMap 基礎上擴展了導航相關的方法
-
ConcurrentNavigableMap 在 NavigableMap 基礎上支持併發操作
後續章節我們逐一分析各接口的主要實現類,以及各個實現類的底層實現原理。
更多相關專欄內容彙總: