第八章 java集合
8.1 java集合
集合用來保存數量不確定的數據,以及保存具有映射關系的數據。也被稱為容器類。集合類都位于java.util包下。集合只能保存對象。
java集合由 collection和map兩個接口派生。
8.2 Collection和Iterator接口
添加對象,刪除對象,清空容器,判斷容器是否為空
當使用System.out.println()時會輸出[ ele1,ele2...]這是因為所有的Collection都重寫了toString的方法。如果想一次訪問集合中的每個元素,需要使用下面的方法遍歷元素。
8.2.1 使用Lambda表達式遍歷集合
Collection可以直接調用foreach(Consumer action)方法,因為Consumer是函數式接口,所以可以用Lambda表達式
8.2.2 使用java8增強的Iterator遍歷集合元素
Iterator也是java集合框架的成員,但是主要用于遍歷Collection中的元素,Iterator對象也被稱為迭代器。
Iterator it=books.iterator();Iterator必須依賴Collection對象
it.hasNext();
it.next();
it.remove();
iterator對集合進行迭代時,只是把集合元素的值傳遞給了迭代變量,所以修改迭代變量的值不會對集合元素本身有任何影響。
如果在iterator迭代collection集合過程中修改collection集合。程序會在運行時發生異常。
8.2.3 使用Lambda表達式遍歷Iterator
forEachRemaining(Consumer action)
8.2.4 使用foreach循環遍歷集合元素
for(Object obj:book)
8.2.5 使用java8新增的predicate操作集合
removeIf(predicate filter)把滿足predicate的方法留下來
8.2.6使用java新增的Stream操作集合
Stream是一個通用的流接口,
獨立使用Stream的步驟:
1.調用Builder()
2.add()
3 調用build()
4.使用聚集方法,大部分聚集方法,每個只能執行一次
Stream提供了大量的方法進行聚類操作
分為:中間方法 末端方法
有狀態的方法 短路方法
8.3 Set集合
實際上Set就是Collection ,只是Set不允許包含重復元素。
8.3.1 HashSet類
HashSet是Set接口的典型實現,HashSet按Hash算法來存儲集合中的元素,因此具有很好的存取和查找性能
特點:
- 不能保證順序
- 不是同步的
- 集合元素值可以是null
HashSet集合判斷兩個元素相等的標準是兩個對象通過equals()方法比較相等,并且兩個對象的hashCode()方法返回值也是相等的。
如果多個元素的 hashCode值相同,但是它們通過equals返回false,則需要在一個桶里面保存多個元素,導致性能的下降。
重寫hashCode()方法的基本規則 - 在程序運行過程中,同一個對象多次調用hashCode()返回值相同
- 當兩個對象通過equals()方法返回true時,這兩個對象的hashCode()方法返回值相同
- 對象用作equals()方法比較標準的實例變量,都應該用于計算hashcode值
注意?:當程序吧對象添加到hashSet后,盡量不要更改集合元素中參與計算hashCode() equals()的實例變量,否則將導致無法正確操作這些元素。
8.3.2 LinkedHashSet
LinkedHashSet是HashSet的子類,但是總是按照添加的順序保存對象。但是仍然不能有重復。
8.3.3 TreeSet類
TreeSet類是SortedSet接口的實現類。TreeSet可以確保集合元素處于排序狀態。
1.自然排序
調用集合元素的compareTo(Object obj)來比較元素之間的大小關系,然后把集合元素按升序排列。
注意?:
試圖把一個對象加入TreeSet時,該對象必須實現Comparatable接口,否則程序將拋出異常。
總結一句話:TreeSet如果想正常運行,必須只能添加同一種類型的對象。
TreeSet集合判斷兩個對象是否相等的唯一標準是:兩個對象通過compareTo()方法比較是否返回0。
注意?:不要修改TreeSet集合元素的關鍵實例變量。
2.定制排序
實現定制排序,在創建TreeSet對象時,提供一個Comparator對象與該TreeSet集合關聯,由該Comparator對象負責集合元素的排序邏輯。
EnumSet類
EnumSet是專門為枚舉類設計的集合類,EnumSet中所有元素都必須是指定枚舉類型的枚舉值,元素是有序的,EnumSet以枚舉值在Enum類內定義順序來決定集合的順序,
EnumSet 集合不允許加入null, 且必須用類方法創建。
當試圖復制一個Collection集合里的元素來創建EnumSet集合時,必須保證Collection集合里面的所有元素都是同一個枚舉類的枚舉值。
8.3.5 各Set實現類的性能分析
HashSet性能總是比TreeSet好,
只有當需要一個保持排序的Set時,在應該使用TreeSet'
LinkHashSet遍歷起來更加方便,普通的操作不如HashSet
EnumSet性能最好,但是有局限
這三個都是線程不安全的。必須手動同步。
8.4 List集合
List集合代表一個元素有序,可重復的集合。集合中每個元素都有其對應的順序索引。
8.4.1 java8改進的List接口和ListIterator接口
List集合增加了一些根據索引來操作集合元素的方法。
List判斷兩個對象相等只要通過equals()方法比較返回true.
set(int index,Object element)方法不會改變List集合的長度。
ListIterator方法來遍歷List元素。它增加了向前迭代的功能。hasPrevious() lit.previous()
8.4.2 ArrayList和vector實現類
不要用vector stack
用ArrayList ArrayDeque
8.4.3 固定長度的List
有一個操作數組的工具類Arrays,有一個asList()方法,可以把一個數組或者指定個數的對象轉換成list集合,這個集合時Array的內部類ArrayList的實例,時固定長度的List集合。
8.5 Queue集合
Queen用于模擬隊列這種數據結構,隊列通常是“先進先出”的容器。
8.5.1 PriorityQueen實現類
PriorityQueen是一個比較標準隊列實現類,因為保存隊列元素的順序并不是按照加入的順序,而是按照隊列元素的大小重新排列。
注意?:不允許插入null元素
8.5.2 Deque接口與ArrayDeque實現類
Deque接口是Queen 接口的子接口,代表一個雙短隊列
Deque接口提供了一個典型的實現類:ArrayDeque。基于數組實現的雙端隊列。既可以當棧,也可以當隊列。當棧的話,就用push peek pop
當隊列的話,就用offer peek poll.
8.5.3 LinkedList實現類
既可以當棧,也可以當隊列
8.5.4 各種線性表的性能對比
- 如果需要遍歷集合元素,ArrayList更好,使用隨機訪問方法(get)來遍歷
- 如果經常執行插入刪除,LinkedList更好
- 如果多個線程同時訪問List 集合中元素,考慮使用Collections將集合包裝成線程安全
8.6 java8增強的Map集合
Map又叫字典,或者關聯數組。
8.6.2 java8改進的HashMap和Hashtable實現類
判斷兩個key相等的條件:兩個key通過equals()比較返回true,并且hatched相等。
判斷兩個value相等的雕件:通過equals返回true
注意?:盡量不要使用可變對象作為hashmap的key,如果做了,也盡量不要改變。
8.6.3 LinkedHashMap實現類
使用雙向鏈表維護key-value的次序,迭代順序與key-value對的插入順序一致
8.6.4 使用Properties讀寫屬性文件
可以把map對象和屬性文件聯系起來,從而把Map 對象中的key-value對寫入屬性文件,也可以把文件中的key-value加載到map中,key和value都是字符串類型。
8.6.5 SortedMap接口和TreeMap實現類
8.6.6 WeakHashMap實現類
8.6.7 IdentityHashMap
當且僅當兩個key嚴格相等(==),才認為兩個key相等。
8.6.8 EnumMap實現類
8.6.9 性能分析
HashMap最常用
8.7 HashSet和HashMap的性能選項
負載極限