集合:是一種容器,用來裝對象的容器,不能裝基本數據類型。html
數組也是容器,能夠用來裝基本數據類型,也能夠用來裝對象。java
本質上,集合須要用對應的數據結構實現,是多個類實現接口Collection系列和Map接口的統稱數組
Collection 表示一組對象,這些對象也稱爲 collection 的元素。一些 collection 容許有重複的元素,而另外一些則不容許。一些 collection 是有序的,而另外一些則是無序的。安全
數據結構
Collection方法:框架
歸類 | 方法簽名 | 方法描述 | |
---|---|---|---|
1 | 添加 | add(E e) | 添加一個元素對象到當前集合中 |
2 | 添加 | addAll(Collection<? extends E> other) | 添加多個元素,把other集合的全部元素都添加到當前集合中,this = this ∪ other; |
3 | 刪除 | clear() | 清空集合 |
4 | 刪除 | remove(Object obj) | 刪除一個元素,根據元素的equals()來判斷是不是要被刪除的元素,若是元素的類型沒有重寫equals方法,那麼等價於==,若是重寫了equals,那麼就按照equals的規則來比較,通常比較內容。 |
5 | 刪除 | removeAll(Collection<?> coll) | 刪除多個元素,把當前集合中和c共同的元素刪除,即this = this - this ∩ coll;子集 |
6 | 刪除 | retainAll(Collection<?> coll) | 刪除多個元素,在當前集合中保留和c的共同的元素,即this = this ∩ coll;交集 |
7 | 查 | int size() | 獲取元素的個數 |
8 | 查 | boolean contains(Object obj) | 是否包含某個元素。根據元素的equals()來判斷是不是要被刪除的元素,若是元素的類型沒有重寫equals方法,那麼等價於==,若是重寫了equals,那麼就按照equals的規則來比較,通常比較內容。 |
9 | 查 | boolean containsAll(Collection<?> coll) | 是否包含多個元素。判斷當前集合中是否包含coll集合的全部元素,即coll是不是this的子集。 |
10 | 查 | boolean isEmpty() | 集合是否爲空 |
11 | 遍歷 | Object[] toArray() | 將集合中的元素用數組返回 |
12 | 遍歷 | Iterator iterator() | 返回一個迭代器對象,專門用於遍歷集合 |
即Collection集合元素的通用獲取方式。每一種實現了Iterable接口的集合內部,都會有一個內部類實現了Iterator接口工具
public boolean hasNext()
【若是仍有元素能夠迭代,則返回 true。】性能
public E next()
【返回迭代的下一個元素。】在調用Iterator的next方法以前,迭代器的索引位於第一個元素以前,指向第一個元素,當第一次調用迭代器的next方法時,返回第一個元素,而後迭代器的索引會向後移動一位,指向第二個元素,依此類推,直到hasNext方法返回false,表示到達了集合的末尾,終止對元素的遍歷。this
在進行集合元素取出時,若是集合中已經沒有元素了,還繼續使用迭代器的next方法,將會發生java.util.NoSuchElementException沒有集合元素的錯誤spa
注意:不要在使用Iterator迭代器進行迭代時,調用Collection的remove(xx)方法,不然會報異常java.util.ConcurrentModificationException,或出現不肯定行爲。
for(元素的數據類型 變量 : Collection集合or數組){
//寫操做代碼
}
java.lang.Iterable接口,實現這個接口容許對象成爲 "foreach" 語句的目標。
java.lang.Iterable接口的抽象方法:
public Iterator iterator(): 【獲取對應的迭代器】
foreach本質上就是使用Iterator迭代器進行遍歷的。
因此也不要在foreach遍歷的過程使用Collection的remove()方法。
若是在Iterator、ListIterator迭代器建立後的任意時間從結構上修改了集合(經過迭代器自身的 remove 或 add 方法以外的任何其餘方式),則迭代器將拋出 ConcurrentModificationException。這就是Iterator迭代器的快速失敗(fail-fast)機制。
結構性修改是指:改變list的size大小,或者,以其餘方式改變他致使正在進行迭代時出現錯誤的結果。
那麼如何實現快速失敗(fail-fast)機制的呢?
在ArrayList等集合類中都有一個modCount變量。它用來記錄集合的結構被修改的次數。
當咱們給集合添加和刪除操做時,會致使modCount++。
而後當咱們用Iterator迭代器遍歷集合時,建立集合迭代器的對象時,用一個變量記錄當前集合的modCount。例如:int expectedModCount = modCount;
,而且在迭代器每次next()迭代元素時,都要檢查 expectedModCount != modCount
注意,迭代器的快速失敗行爲不能獲得保證,
自定義類時若是一個實現類不但願提供fail-fast迭代器,則能夠忽略這個字段。
它是一個帶有索引的集合,經過索引就能夠精確的操做集合中的元素(與數組的索引是一個道理)。
集合中能夠有重複的元素,經過元素的equals方法,來比較是否爲重複的元素。
ArrayList:動態數組 Vector:動態數組 LinkedList:雙向鏈表 Stack:棧
一、添加元素
void add(int index, E ele) 【在[index]位置添加一個元素】
boolean addAll(int index, Collection<? extends E> eles) 【在[index]位置添加多個元素】
二、獲取元素
List subList(int fromIndex, int toIndex) 【截取[fromIndex,toIndex)部分的元素】
三、獲取元素索引
int indexOf(Object obj) 【返回obj在當前集合中第一次出現的下標】
int lastIndexOf(Object obj) 【返回obj在當前集合中最後一次出現的下標】
四、刪除和替換元素
E remove(int index) 【刪除[index]位置的元素,返回被刪除的元素】
E set(int index, E ele) 【替換[index]位置的元素,返回被替換的元素】
五、遍歷
ListIterator listIterator() 【默認遊標在[0]開始】
ListIterator listIterator(int index) 【默認遊標在[index]位置】
void set(E e): 【用指定元素替換 next 或 previous 返回的最後一個元素】
void remove(): 【從列表中移除由 next 或 previous 返回的最後一個元素】
boolean hasPrevious(): 【若是以逆向遍歷列表,往前是否還有元素。則返回 true】
E previous(): 【返回列表中的前一個元素。】
int previousIndex(): 【返回列表中的前一個元素的索引】
boolean hasNext() 【以正向遍歷列表時,若是列表迭代器有多個元素,則返回 true】
E next() 【返回列表中的下一個元素。】
int nextIndex() 【返回對 next 的後續調用所返回元素的索引。】
Set 集合不容許包含相同的元素,若是試把兩個相同的元素加入同一個 Set 集合中,則添加操做失敗。
Set集合支持的遍歷方式和Collection集合同樣:foreach和Iterator。
HashSet 是 Set 接口的典型實現,大多數時候使用 Set 集合時都使用這個實現類。
java.util.HashSet
底層的實現實際上是一個java.util.HashMap
支持,而後HashMap的底層物理實現是一個Hash表。
HashSet/LinkedHashSet:
底層結構:裏面維護了一個TreeMap,都是基於紅黑樹實現的!
特色: 一、不容許重複 二、實現排序, 天然排序或定製排序
若是使用的是天然排序(Comparable),則經過調用實現的compareTo方法
天然排序:它判斷兩個對象是否相等的惟一標準是:兩個對象經過 compareTo(T o) 方法比較返回值爲0。
若是使用的是定製排序(Comparator),則經過調用比較器的compare方法
Collection
中的集合稱爲單列集合,Map
中的集合稱爲雙列集合。java.util.Map<K,V>
一、存儲鍵值對(key,value),也稱爲映射關係,鍵值對是Map.Entry接口的實現類對象。
二、全部存儲到Map中的key不能重複, 每一個鍵只能對應一個值(這個值能夠是單個值,也能夠是個數組或集合值)。
一、添加
V put(K key, V value): 【將一對鍵值對添加到當前map中,同一個key若是put兩次,第二次會覆蓋上次的value】
void putAll(Map m): 【將另外一個map中的全部鍵值對添加到當前map中】
二、刪除
void clear(): 【清空全部映射關係】
V remove(Object key): 【根據key刪除一整對鍵值對(key,value)】
三、查詢
int size(): 【返回鍵值對的數量】
boolean containsKey(Object key): 【是否包含某個key】
boolean containsValue(Object value): 【是否包含某個value】
V get(Object key): 【根據key獲取value值,若是此映射不包含該鍵的映射關係,則返回 null
。】
boolean isEmpty() 【若是此映射未包含鍵-值映射關係,則返回 true。】
四、遍歷
Set<Entry<K,V>> entrySet() 【遍歷全部的鍵值對,映射關係的 Set
視圖 】
Set<K> keySet() 【遍歷全部的key,鍵的 Set
視圖】
Collection<V> values() 【遍歷全部的value,值的 Collection
視圖】
若指定的鍵(key)在集合中存在,則返回值爲集合中鍵對應的值(該值爲替換前的值),並把指定鍵所對應的值,替換成指定的新值。
Map的遍歷,不能支持foreach
(1)分開遍歷:
單獨遍歷全部key
單獨遍歷全部value
(2)成對遍歷:
Map接口的經常使用實現類:HashMap、TreeMap、LinkedHashMap和Properties。其中HashMap是 Map 接口使用頻率最高的實現類。
HashMap和Hashtable都是哈希表。
Hashtable是線程安全的,任何非 null 對象均可以用做鍵或值。不容許null鍵
HashMap是線程不安全的,並容許使用 null 值和 null 鍵。
Properties 類是 Hashtable 的子類,Properties 可保存在流中或從流中加載。屬性列表中每一個鍵及其對應值都是一個字符串。
存取數據時,建議使用setProperty(String key,String value)方法和getProperty(String key)方法。
更多方法請見API文檔
我們存到Set中只有一個元素,又是怎麼變成(key,value)的呢?
原來是,把添加到Set中的元素做爲內部實現map的key,而後用一個常量對象PRESENT對象,做爲value。