Java 集合框架主要包括兩種類型的容器,一種是集合(Collection),存儲一個元素集合,另外一種是圖(Map),存儲鍵/值對映射。Collection 接口有 3 種子類型,List、Set 和 Queue,再下面是一些抽象類,最後是具體實現類。java
接口:表明集合的抽象數據類型。例如 Collection、List、Set、Queue、Map 等,這些接口以不一樣的方式操做集合對象。算法
具體類:集合接口的具體實現。從本質上講,它們是可重複使用的數據結構,例如:ArrayList、LinkedList、HashSet、HashMap。編程
算法:是實現集合接口的對象裏的方法執行的一些有用的計算,例如:搜索和排序。Collections和Arrays提供了這些算法的實現。數組
下圖是《Java編程思想》給出的Java集合框架:安全
點線框表示接口;實線框表示具體類;帶空心箭頭的點線表示一個特定的類實現了一個接口;帶實心箭頭的點線表示某個類能夠生成箭頭所指的對象;數據結構
迭代器:迭代器就是對「逐一訪問全部元素」這一操做的抽象。實際上就是對一組對象之間的位置,直接後繼等關係的集成。框架
對序列進行遍歷時,迭代器始終維護一個當前元素,而且提供訪問序列下一個元素的機制,第一次對「訪問下一個元素」操做的訪問就會給出最初始的當前元素。ide
於是,根據這些描述,則迭代器必須有:函數
boolean hasnext() //檢查是否有剩餘元素 E getnext() //返回下一元素
Iterator接口就是Java在Util包中提供的一個迭代器接口,其思路是經過iterator方法,每一個集合都可建立並返回給客戶一個實現了Iterator接口的對象,而且將當前位置的概念在對象內部存儲下來。this
其定義爲:
public interface Iterator<E>{ boolean hasNext(); E next(); void remove(); //移除迭代器返回的最後一個元素 }
對於remove()操做,須要注意的是,調用一次remove()以後,不能再次調用該方法,除非又一次調用了next()方法。
Iterable接口返回的是Iterator接口的一個實例,設置這一接口是爲了讓容器能有不一樣的遍歷方式,經過繼承Iterable接口,就能實現多個不一樣的Iterator類,例如前向迭代、反向迭代、隨機迭代等等。
public interface Iterable<T> { Iterator<T> iterator(); }
1.Iterator接口的核心方法next()或者hasNext() 是依賴於迭代器的當前迭代位置的。 若是Collection直接實現Iterator接口,勢必致使集合對象中包含當前迭代位置的數據(指針)。當集合在不一樣方法間被傳遞時,因爲當前迭代位置不可預置,那麼next()方法的結果會變成不可預知。 除非再爲Iterator接口添加一個reset()方法,用來重置當前迭代位置。但即時這樣,Collection也只能同時存在一個當前迭代位置。而Iterable則否則,每次調用都會返回一個從頭開始計數的迭代器。多個迭代器是互不干擾的。
2.如上所說,讓集合能夠有更加靈活的迭代方式。
當編譯器看到一個正在用於Iterable對象的加強for循環時,它用對iterator方法的那些調用代替加強for循環以獲得一個Iterator對象,而後調用其方法。
例如:
public static <E> void print(Collection<E> collection){ for(E item:collection){ System.out.println(item); } }
編譯器將其重寫爲:
public static <E> void print(Collection<E> collection){ Iterator<E> it = collection.iterator(); while (it.hasNext()){ E item = it.next(); System.out.println(item); } }
Collection抽象了集合的概念,它存儲一組同一類型的對象。其關鍵接口(部分)以下:
public interface Collection<E> extends Iterable<E>{ int size(); //返回元素數量 boolean isEmpty(); //判斷是否爲空 void clear(); //清空集合 boolean contains(E x); //判斷是否包含某元素 boolean add(E x); //添加某元素 boolean remove(E x); //移除某元素 Iterator<E> iterator(); //返回一個迭代器 Object[] toArray(); //返回一個由這些元素組成的對象數組 }
Map是一種存放一組條目的容器,條目是一種形如(key,value)的組合對象。其關鍵接口(部分)以下:
public interface Map<K,V>{ int size(); boolean isEmpty(); void clear(); boolean containsKey(Object Key); //判斷是否包含某鍵 boolean containsValue(Object value); //判斷是否包含某元素 V get(Object key); //獲取某鍵對應的元素 V put(K key,V value); //添加某鍵值對 V remove(Object key); //移除某鍵對應的鍵值對 V replace(K key,V value); //僅當某鍵對應有值時替換該值 boolean replace(K key,V oldValue,V newValue); //替換爲新值,若無對應舊值,則添加 }
Comparator是比較器接口,能夠實現比較器接口來構建一個比較器,即定義了該類的實例的大小規則。經常使用方法是將其提供給序列的排序函數。
其定義爲:
public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }
值得注意的是,任何對象都已實現了equals(Object obj)方法,故實現Comparator接口時可只實現compare方法不實現equals方法。
Comparable能夠看做排序接口,任何實現了Comparable接口的類可支持排序,將其稱做」天然排序「。例如某list中的類實現了Comparable接口,那麼可使用Collections.sort(list)來對list進行排序。
其定義爲:
public interface Comparable<T>{ int comparaTo(T o); }
值得注意的是,須要確保ComparaTo方法與equals方法的結果保持一致,不然會出現一些問題(在有序集或有序映射與天然排序一塊兒使用時會表現會超出預期,顯得奇怪),於是建議重寫equals方法。
綜上來講,能夠將Comparable接口看做」內部比較器",類實現了comparable接口以後,能夠直接調用排序方法;而能夠將Comparator接口看做」外部比較器「,當類的設計者沒有考慮類的排序時,能夠將類與Comparator接口綁定,從而實現排序。
一個實例:
import java.util.*; public class Test { public static void main(String[] args) throws InterruptedException { ArrayList<Person> list = new ArrayList<>(); list.add(new Person("Ming",171)); list.add(new Person("Hong", 165)); list.add(new Person("Xi",165)); list.add(new Person("Long",181)); System.out.println(list); Collections.sort(list); //使用天然排序 System.out.println(list); Collections.sort(list,new PersonComparator()); //使用外接比較器排序 System.out.println(list); } private static class Person implements Comparable<Person>{ String name; int tall; Person(String name, int tall) { this.name = name; this.tall = tall; } public String toString(){ return name + "-"+ tall; } @Override public int compareTo(Person person) { //實現天然排序接口,按照名字排序 return name.compareTo(person.name); } boolean equals(Person person){ //重寫equals規則 if (this.name.equals(person.name)){ return true; } return false; } } static class PersonComparator implements Comparator<Person> { //實現比較器接口,按照身高排序 @Override public int compare(Person p1, Person p2) { return p1.tall - p2.tall; } } } //結果 [Ming-171, Hong-165, Xi-165, Long-181] [Hong-165, Long-181, Ming-171, Xi-165] [Hong-165, Xi-165, Ming-171, Long-181]
Collections僅包含對集合進行操做或返回集合的靜態方法,它包含對集合操做的多態算法。其中部分關鍵API以下(參數已省略):
public class Collections extends Object{ boolean addAll(); //爲集合添加給定元素 Queue<T> asLifoQueue(); //將Deque變爲先進後出的Queue int binarySearch(); //二分查找某對象 xxx checkedxxx(); //返回指定xxx的動態類型安全視圖 void copy(); //將列表裏因此元素拷貝到另外一個列表 boolean disjiont(); //判斷兩個集合是否有交集 xxx emptyxxx(); //返回一個空的xxx集合 void fill(); //用給定的對象填充集合 int frequency(); //返回集合中等於指定對象的元素數量 int indexOfSubList(); //返回目標列表在源列表的起始位置 int lastindexOfSubList(); //返回目標列表在源列表的結束位置 T max(); T min(); void reverse(); //反轉集合 void rotate(); //按指定距離輪轉集合 void shuffle(); //置亂集合 void sort(); //排序集合 void swap(); //交換指定兩個元素 xxx synchronizedxxx(); //返回線程安全的xxx xxx unmodifiablexxx(); //返回不可修改的xxx視圖 }
Arrays包含用於操做數組的各類方法以及asList()方法,其部分API以下(參數已省略):
public class Arrays extends Object{ List<T> asList(T... a) //給定對象建立一個列表 int binarySearch(); //二分查找某值 int compare(); //按字典順序比較兩個值 int compareUnsigned(); //按字典順序比較兩個值,這兩個值視爲無符號的 xxx copyOf(); //拷貝數組指定長度的元素 xxx copyOfRange(); //指定起始位置和長度來拷貝數組元素 int mismatch(); //查找兩個數組第一個不匹配的索引 void parallelPrefix(); //並行地對給的子數組的全部元素施加某種操做 void parallelSetAll(); //使用生成器函數並行地設置給的子數組的全部元素 void parallelSort(); //並行排序 void sort(); //排序 Spliterator<T> Spliterator(); //返回覆蓋指定數組地拆分器 Stream<T> Stream(); //返回指定數組元素構成的流 String toString(); boolean equals(); //判斷兩元素是否相等 void fill(); //以指定元素填充數組 int hashCode(); boolean deepEquals(); //deepxxx適用於嵌套數組的狀況 int deepHashcode(); String deepToString(); }
後續爲集合框架中的那些實現類以及對應的數據結構。