集合
1.集合體系

Collection(集合的根接口) --> Iterable(接口)
Collection
-
List接口
有序 (記錄元素的添加順序) 可以重復(fù)
-
AbstractList(抽象類)
ArrayList [數(shù)組結(jié)構(gòu)]
-
Vector [數(shù)組結(jié)構(gòu)]
- Stack
LinkedList[鏈表結(jié)構(gòu)]
-
-
Queue接口
- Deque接口
- LinkList[鏈表結(jié)構(gòu)]
- Deque接口
-
Set接口
無序 (不記錄元素的添加順序) 不能重復(fù)
- AbstractSet抽象類
TreeSet[紅黑樹結(jié)構(gòu)]
-
HashSet[哈希表結(jié)構(gòu)]
- LinkHashSet[鏈表+哈希表]
- SortedSet接口
- AbstractSet抽象類
Map接口
-
AbstractMap抽象類
- HashMap
- TreeMap
-
HashTable
- Properties
在集合的接口規(guī)范中,我們不難發(fā)現(xiàn),包含的是對數(shù)據(jù)的CRUD
添加: add() addAll()
查詢: contains(Object o)
刪除: remove(Object o)
注意: 集合只能存儲對象!
2.List
特點:
有序 (記錄元素的添加順序) 可以重復(fù)
查詢:get()方法, 根據(jù)索引查 indexOf()方法,查詢對象的索引
修改:set()方法
2.1 Vector
Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
- 基于數(shù)組結(jié)構(gòu)
- 實現(xiàn)可增長的對象數(shù)組,使用整數(shù)索引進(jìn)行訪問,大小可以根據(jù)需要增大或者縮小
無參構(gòu)造默認(rèn)內(nèi)部數(shù)組長度為10.
線程安全,不效率
是Java1.0就有了,屬于老古董
2.2 Stack
Stack<E> extends Vector<E>
表示后進(jìn)先出, 繼承于Vector類,Vector類的方法在Stack中都能使用
Stack() 創(chuàng)建一個空堆棧
push() 把一個對象壓進(jìn)堆棧
peek() 查看棧頂?shù)膶ο?
pop() 移除堆棧頂部的對象, 并返回該對象
empty() 堆棧是否為空
search() 在棧中查找對象, 并確定到棧頂?shù)木嚯x
- 線程安全,不效率
2.2 ArrayList
ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
基于數(shù)組結(jié)構(gòu)
使用上大致是跟Vector一致的,允許所有元素(包括null)
-
默認(rèn)無參構(gòu)造創(chuàng)建對象時沒有長度,在需要存儲元素的時候才進(jìn)行擴(kuò)容
add() 添加一個元素 addAll() 添加另一個集合中的所有元素 ArrayList 不是線程安全的, 效率高
2.3 LinkedList
LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable
允許所有元素(包括null)
底層基于鏈表、雙向隊列數(shù)據(jù)結(jié)構(gòu)集合
List接口的鏈表實現(xiàn),支持List的通用方法
-
為首尾元素的操作提供了特定的方法, 允許作為堆棧,隊列,雙向隊列
offerFirst() 添加頭元素 offerLast() 添加尾元素 pollFirst() 移除頭元素 pollLast() 移除尾元素 peekFirst() 查看頭元素 peekLast() 查看尾元素 線程不安全,處理首尾元素效率高
2.4 集合的迭代
所謂迭代,就是訪問集合中的每一個元素
-
for循環(huán)
使用for循環(huán)訪問數(shù)組中的元素,依賴的是數(shù)組的索引
-
Iterator
不是所有集合都可以使用
-
面向?qū)ο蟮淖龇?把迭代集合的操作封裝成一個對象
Iterator it = list.iterator(); while(it.hasNext()){ Object obj = it.next();//取出下一個元素 } -
常用方法
hasNext() 是否有下一個元素, 判斷當(dāng)前索引是否等于集合長度,不等則返回true,表示還有元素可以迭代. next() 先返回當(dāng)前索引的元素,然后索引+1 remove() 刪除元素 在迭代的過程中只能使用迭代器操作源集合的元素
-
ListIterator
Iterator的子接口,并且功能更加的強(qiáng)大
-
包含了CRUD的方法
ListIterator it = list.listIterator(); //從頭到尾迭代 while(it.hasNext()){ it.next();//獲取下一元素 it.set("111");//替換和刪除原理是一樣的,必須先next()移位 } it.add("222");//往集合里添加元素 //從尾到頭迭代 while(it.hasPrevious){ it.previous();//取出上一元素 } 只有List集合中才有
-
foreach
-
語法糖,底層是Iterator
for(Object obj : list){ .... } 只要實現(xiàn)了Iterable接口就可以用foreach迭代
-
迭代集合總學(xué)了3種方式:在迭代的過程中如果要操作集合,建議使用迭代器,僅僅是要訪問元素就使用foreach會簡單一些
2.5 泛型
類型的不確定,但是使用邏輯一樣
-
集合使用泛型和沒有使用泛型的區(qū)別
-
沒有泛型
取出集合中的元素對象,要調(diào)用到元素對象子類特有的方法,必須強(qiáng)轉(zhuǎn)(不安全) 到處都是警告 -
使用泛型
使用的時候限定了只能存儲對應(yīng)的類型,其他的類型不能存儲進(jìn)來 使用里面的對象時不需要強(qiáng)轉(zhuǎn) 如果要存儲多種類型的數(shù)據(jù),建議分開存儲 沒有警告
-
泛型只是語法糖,當(dāng)取出并使用集合里的對象時,底層是編譯器幫我們強(qiáng)轉(zhuǎn),有編譯器來強(qiáng)轉(zhuǎn)保證安全
-
泛型的作用域
-
聲明在類上,在整個類中有效
class test<E>{ ... } -
聲明在方法上,只在當(dāng)前的方法中有效
/** * 這才是一個真正的泛型方法。 * 首先在public與返回值之間的<T>必不可少,這表明這是一個泛型方法,并且聲明了一個泛型T * 這個T可以出現(xiàn)在這個泛型方法的任意位置. */ public <T> T showKeyName(Generic<T> container){ System.out.println("container key :" + container.getKey()); //當(dāng)然這個例子舉的不太合適,只是為了說明泛型方法的特性。 T test = container.getKey(); return test; } * 泛型的數(shù)量也可以為任意多個 如:public <T,K> K showKeyName(Generic<T> container){ ... }
-
-
問號的使用
泛型中使用問號的3種情況:
1.?:未知類型 2.? super BaseClass:必須是BaseClass類型的父類或者BaseClass類型 3.? extends BaseClass:必須是BaseClass類型的子類或者BaseClass類型
3.Set
特點:
無序不重復(fù),不包含重復(fù)元素,最多包含一個null元素
3.1 HashSet
HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable
哈希表數(shù)據(jù)結(jié)構(gòu)
無序,不能重復(fù)
無參構(gòu)造創(chuàng)建一個HashMap,默認(rèn)初始容量為16
-
add() 方法添加對象,需要判斷兩個點
1.調(diào)用需添加對象的的hashCode()方法,對比set中已存在對象的hash是否相等
2.調(diào)用添加對象的equals()方法,與set中已存在對象進(jìn)行比較
只有以上兩點都返回true時,set才會添加新對象.
HashCode集合判斷是否重復(fù)的關(guān)鍵就在于 Object的hashCode和equals方法
線程不安全
3.2 LinkedHashSet
LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, Serializable
基于鏈表和哈希表的結(jié)構(gòu)
使用鏈表來記錄對象添加的順序,使用哈希表來判定元素的唯一
底層是創(chuàng)建了一個初始容量為16的LinkedHashMap
沒有自己的特定方法,使用上和set接口一致
3.3 TreeSet
TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable
底層是紅黑樹數(shù)據(jù)結(jié)構(gòu),將集合中的對象進(jìn)行比較,重復(fù)的則不添加
基于TreeMap實現(xiàn)
-
默認(rèn)無參構(gòu)造是基于自然順序排序(從小到大), 自定義的對象添加到TreeSet里面,需要實現(xiàn)Comparable接口
當(dāng)前對象實現(xiàn)Comparable接口的compareTo(A a)方法,返回值1表示比指定對象a大,0 表示相等, -1 表示比指定對象a小.
compareTo()方法是自然比較方法
-
如果不想按自然順序排序,TreeSet構(gòu)造器還可以傳入Comparator進(jìn)行自定義排序,比如從大到小
public TreeSet(Comparator<? super E> comparator) { throw new RuntimeException("Stub!"); }Comparator
int compare(T var1, T var2); var1 > var2 返回1 var1 == var2 返回0 var < var2 返回-1 以上返回值會使集合按照從小到大排序 分析TreeSet中的TreeMap可以發(fā)現(xiàn),優(yōu)先使用Comparator的compare()進(jìn)行排序,如果沒有Comparator,則使用對象的compareTo()方法進(jìn)行排序
4.Map
表示映射關(guān)系,以鍵值對key-value形式存在
-
特點:
key無序不重復(fù),value可重復(fù)
一個key只能映射一個值
Map是存儲了多個鍵值對 Map.Entry<k,v> 的集合
-
常用方法
put(k,v) 添加元素 get(k) 返回指定key的值 keySet() 以set集合返回所有的key values() 以Collection的形式返回所有的值 size() 獲得鍵值對的個數(shù) entrySet() 返回Entry<k,V>的set集合 HashMap<String,Object> map = new HashMap<>(); Set<Map.Entry<String, Object>> entries = map.entrySet(); for (Map.Entry<String, Object> entry : entries){ String key = entry.getKey(); //鍵 Object value = entry.getValue(); //值 }
4.1 HashMap
基于哈希表的Map接口的實現(xiàn)類
非同步,允許使用null鍵和null值,除此之外,與HashTable類大致相同
4.1 TreeMap
作為key的元素,需要實現(xiàn)hashCode()和equals()之外,還需要實現(xiàn)Comparable接口,重寫compareTo()方法,compareTo()方法需要正確返回整數(shù),負(fù)數(shù)以及0
treeMap 與 hashMap不同,hashMap需要根據(jù)equals方法來判斷key是否相等,而treeMap是根據(jù)
compareTo() == 0 判斷是否相等.
4.2 Map和set的關(guān)系
Set底層是用Map數(shù)據(jù)結(jié)構(gòu),xxxSet底層就用xxxMap數(shù)據(jù)結(jié)構(gòu),如HashSet --> HashMap
-
Set集合不會重復(fù)的關(guān)鍵:
Set集合的元素是底層Map用key來保存,用一個常量作為value,
所有的key都映射到這個常量,滿足鍵值對的要求,key的不重復(fù)特性保證了Set的元素是不重復(fù)的
5.集合相關(guān)類
5.1 Collections
- 集合的工具類
-
常用方法:
shuffle() 打亂集合中元素的順序
sort() 對集合中的元素進(jìn)行排序
synchronizedCollection(Collection<T> c):返回線程安全(同步)的collection
synchronizedMap(Map<k,v> m):返回線程安全(同步)Map
-
使用線程安全的集合需要注意的地方:
進(jìn)行迭代的時候,迭代的代碼必須同步
List<String> list = new ArrayList<>(); Collection<String> collection = Collections.synchronizedCollection(list); synchronized (collection){ //迭代需要進(jìn)行同步 Iterator<String> iterator = collection.iterator(); while (iterator.hasNext()){ iterator.next(); } }
5.2 Arrays
Arrays.asList(T... t) 目的是將數(shù)組轉(zhuǎn)成集合,得到的集合不允許刪除,增加,只能查詢