從0開始復(fù)習java(5)--Collection

Java 集合類是一種特別有用的工具類,大致可分為Set螃诅、List啡氢、QueueMap四種體系术裸。

Set代表無序倘是、不可重復(fù)的集合;
List代表有序袭艺、重復(fù)的集合搀崭;
Map代表具有映射關(guān)系的集合;
Queue代表隊列集合猾编。

一瘤睹、集合概述

Java5在java.util.concurrent包下提供了一些多線程支持的集合類。

集合里只能保存對象答倡。

Java的集合類主要由兩個接口派生:CollectionMap轰传。

Collection體系的繼承樹
Collection體系的繼承樹

上圖中Deque還有一個實現(xiàn)類ArrayDeque,只是我沒有找到合適的圖瘪撇。获茬。

Map體系的繼承樹
Map體系的繼承樹

最常用的集合類有:HashSet港庄、TreeSet、ArrayDeque恕曲、ArrayList鹏氧、LinkedList、HashMap佩谣、TreeMap

二把还、Collection和Iterator接口

Collection接口里面定義了如下操作集合元素的方法:

  • boolean add(Object o)
  • boolean addAll(Collection c)
  • void clear()
  • boolean contains(Object o)
  • boolean isEmpty()
  • Iterator iterator()
  • boolean remove(Object o)
  • boolean removeAll(Collection c)
  • boolean retainAll(Collection c)
  • int size()
  • Object[] toArray()

使用lambda表達式遍歷集合

Java8為Iterable接口新增了一個forEach(Consumer action)默認方法,該方法所需參數(shù)的類型是一個函數(shù)式接口茸俭,Iterable接口是Collection接口的父接口吊履,Collection集合可以使用這個接口。

books.forEach(obj -> System.out.println(obj));

使用Java8增強的Iterator遍歷集合元素

Iterator接口提供了4中方法:

  • boolean hasNext()
  • Object next()
  • void remove()
  • void forEachRemaining(Consumer action)
Iterator it = books.iterator();
while(it.hasNext){
    String book = (String)it.next();
}

Iterator必須依附于Collection對象瓣履。

使用Lambda表達式遍歷Iterator

it.forEachRemaining(obj->System.out.println(obj));

使用foreach循環(huán)遍歷集合元素

使用Java8新增的predicate操作集合

Java8為Collection集合新增了一個removeIf(Predicate filter)方法率翅,批量刪除符合filter的元素。

books.removeIf(obj->((String)obj).length()<10);

使用Java8新增的Stream操作集合

Java8新增了Stream袖迎,IntStream冕臭,LongStreamDoubleStream等流式API燕锥,這些API代表多個支持串行和并行聚集操作的元素辜贵。還有每個Stream提供了Builder,如Stream.Builder归形,IntStream.Builder托慨,開發(fā)者可以通過這些Builder來創(chuàng)建對應(yīng)的流。

獨立使用Stream的步驟:

  1. 使用Stream的builder類方法創(chuàng)建Builder
  2. 重復(fù)調(diào)用Builder的add方法添加元素
  3. 調(diào)用Builder的build方法獲取對應(yīng)的流
  4. 調(diào)用Stream的聚集操作

Stream提供了大量的方法暇榴,有"中間方法"(生成另外一個流)和"末端方法"(對流的最終操作)厚棵。

常用的中間方法:

  1. filter(Pridicate predicate)
  2. mapToXxx(ToXxxFunction Mapper)
  3. peek(Consumer action)
  4. distict()
  5. sorted()
  6. limit(long maxSize)

常用的末端方法:

  1. forEache(Consumer action)
  2. toArray()
  3. reduce()
  4. min()
  5. max()
  6. count()
  7. anyMatch(Predicate predicate)
  8. allMatch(Predicate predicate)
  9. noneMatch(Predicate predicate)
  10. findFirst()
  11. findAny()

Java8為Collection提供了一個stream默認方法。

三蔼紧、Set集合

HashSet類

特點:

  • 不能保證順序
  • 不能保證同步(多線程)
  • 集合元素值可以是null

當向HashSet集合添加一個元素時婆硬,HashSet會調(diào)用該對象的hashCode()方法得到對象的hashCode值,然后根據(jù)該hashCode值決定該對象在HashSet中的存儲位置奸例。

HashSet集合判斷兩個元素相等的標準是兩個對象通過equals()方法比較相等彬犯,并且兩個對象的hashCode()方法返回值也想等。

重寫hashCode()方法的基本原則:

  • 同一個對象多次調(diào)用應(yīng)該返回相等的值
  • 當兩個對象通過equals()方法比較返回true時查吊,他們的hashCode()值應(yīng)該相等
  • 對象中用于equals()比較的實例變量都應(yīng)該用于計算hashCode

重寫hashCode()的一般步驟:

  1. 把對象內(nèi)每個有意義的實例變量計算出一個int類型的hashCode值谐区。
  2. 用第一步計算的多個hashCode值組合計算出一個hashCode值返回

hashCode值的計算方式:

變量類型 計算方式
boolean f?0:1
整數(shù)類型 (int)f
long (int)(f^(f>>>32))
float Float.floatToIntBits(f)
double d = Double.doubleToLongBits(f);(int)(d^(d>>>32))
應(yīng)用類型 f.hashCode()

為了避免直接相加的偶然相等,可以通過為各實例變量的hashCode值乘以任意一個質(zhì)數(shù)后再相加逻卖。

LinkedHashSet

也是根據(jù)hashCode插入元素宋列,但是要維護元素的插入順序,性能略低于HashSet评也。

TreeSet

TreeSet是SortedSet的實現(xiàn)類炼杖。有幾個額外方法:

  • Comparator comparator()
  • Object first()
  • Object last()
  • Object lower(Object e)
  • Object hight(Object e)
  • SortedSet subSet(Object fromElement, Object toELement)
  • SortedSet headSet(Object toElement)
  • SortedSet tailSet(Object toElement)

TreeSet使用紅黑樹的數(shù)據(jù)結(jié)構(gòu)來存儲集合元素戈鲁。支持自然排序和定制排序。

自然排序

調(diào)用集合的compareTo(Object obj)方法比較元素之間的大小關(guān)系嘹叫,然后按升序排序。

Comparable接口里定義了一個compareTo(Object obj)方法诈乒。

如果試圖把一個對象添加到TreSet罩扇,則該對象的類必須實現(xiàn)Comparable接口。

向TreeSet中插入元素時怕磨,第一個元素不會調(diào)用compareTo()方法

定制排序

創(chuàng)建TreeSet時傳遞給它一個Comparator對象即可喂饥,該接口是函數(shù)式接口,可以使用lambda表達式創(chuàng)建對象肠鲫。

四员帮、List集合

代表一個元素有序、可重復(fù)的集合导饲,集合中每個元素都有其對應(yīng)的順序索引捞高。

java8改進的List接口和ListIterator接口

List接口的方法:

  • void add(int index, Object element)
  • boolean addAll(int index, Collection c)
  • Object get(int index)
  • int indexOf(Object o)
  • int lastIndexOf(Object o)
  • Object remove(int index)
  • Object set(int index, Object element)
  • List subList(int fromIndex, int toIndex)
  • void replaceAll(UnaryOperator operator)
  • void sort(Comparator c)

List判斷兩個對象相等只要通過equals方法返回true即可。

List除了有Set的iterator()方法之外渣锦,還有l(wèi)istIterator()方法硝岗,該方法返回一個ListIterator對象,ListIterator接口繼承于Iterator接口袋毙。ListIterator相較于Iterator多了如下方法:

  • boolean hasPrevious()
  • Object previous()
  • void add(Object o)

ArrayList和Vector實現(xiàn)類

使用initialCapacity參數(shù)設(shè)置該數(shù)組的長度型檀。如果需要向集合中添加大量元素,可使用ensureCapacity(int minCapacity)方法一次性地增加容量听盖,可以減少重分配的次數(shù)胀溺,提高性能。

可以在創(chuàng)建的時候指定initialCapacity皆看,還可以通過一下兩個方式重新分配Object[]數(shù)組仓坞,不指定的話默認長度為10:

  • void ensureCapacity(int minCapacity)
  • void trimToSize()

ArrayList和Vector用法幾乎完全相同,Vector是一個古老的集合悬蔽,里面有重復(fù)的方法扯躺。

通常盡量少用Vector。

Vector是線程安全的蝎困,但效率低录语,ArrayList不是線程安全的,java.util.Collections類可以將ArrayList變成線程安全的禾乘。推薦使用ArrayList澎埠。

Stack是Vector的子類。有以下方法:

  • Object peek()
  • Object pop()
  • void push(Object item)

Stack繼承于Vector始藕,古老的類蒲稳,線程安全氮趋,但是效率低,不建議使用江耀∈P玻可以使用后來的ArrayDeque類代替。

固定長度的List

Arrays類提供了asList(Object... a)方法祥国,可以把一個數(shù)組或指定個數(shù)的對象轉(zhuǎn)換成List集合昵观。這個List集合既不是ArrayList實現(xiàn)類的實例,也不是Vector實現(xiàn)類的實例舌稀,而是Arrays的內(nèi)部類ArrayList的實例啊犬。

Arrays.ArrayList是一個固定長度的List集合,只能遍歷壁查,不可增加修改觉至。

五、Queue集合

Queue接口中定義的方法:

  • void add(Object e)
  • Object element():獲取隊列頭元素睡腿,但不刪除
  • boolean offer(Object e):加入元素语御,比add()好
  • Object peek():獲取頭元素,如果為空席怪,返回null
  • Object poll():獲取頭元素沃暗,并刪除,如果為空何恶,返回null
  • Object remove():獲取頭元素孽锥,并刪除

Deque是Queue的子接口,代表雙端隊列细层。有ArrayDequeLinkedList兩個實現(xiàn)類惜辑。

PriorityQueue實現(xiàn)類

內(nèi)部排序。

Deque接口和ArrayDeque實現(xiàn)類

Deque接口方法:

  • void addFirst(Object e)
  • void addLast(Object e)
  • Iterator descendingIterator()
  • Object getFirst()
  • Object getLast()
  • boolean offerFirst(Object e)
  • boolean offerLast(Object e)
  • Object peekFirst()
  • Object peekLast()
  • Object pollFirst()
  • Object pollLast()
  • Object pop()
  • void push()
  • Object removeFirst()
  • Object removeFirstOccurrence(Object o)
  • Object removeLast()
  • Object removeLastOccurrence(Object o)

LinkedList實現(xiàn)類

LinkedList即可以當成雙端隊列疫赎,也可以當成棧使用盛撑,也可以當成隊列使用。

ArrayList和ArrayDeque內(nèi)部使用數(shù)組實現(xiàn)捧搞,而LinkedList內(nèi)部使用鏈表實現(xiàn)抵卫。

各種線性表的性能分析

整體來說ArrayList比LinkedList性能好。

  1. 如果需要遍歷List胎撇,對于ArrayList介粘、Vector集合,應(yīng)該使用隨機訪問方法(get())遍歷晚树;對于LinkedList則應(yīng)該采用Iterator遍歷姻采。
  2. 經(jīng)常插入刪除袱蜡,考慮使用LinkedList
  3. 多個線程梢卸,可以使用Collections將集合包裝成線程安全的集合。

六赛糟、Java8增強的Map集合

從Java源碼看男摧,Java先實現(xiàn)了Map阁吝,然后通過包裝一個所有value都為null的Map就實現(xiàn)了Set集合声登。

Map的實現(xiàn)子類和子接口中key集的存儲形式和對應(yīng)Set集合中元素的存儲形式完全相同涵紊。

方法:

  • void clear()
  • boolean containsKey(Object key)
  • boolean containsValue(Object value)
  • Set entrySet()

返回Map中包含的key-value對所組成的Set集合,每個集合元素都是Map.Entry對象

  • Object get(Object key)
  • boolean isEmpty()
  • Set keySet()
  • Object put(Object key, Object value)
  • void putAll(Map m)
  • Object remove(Object key, Object value)
  • int size()
  • Collection values()

Map接口中有一個內(nèi)部類Entry蛉签,該類封裝了key-value鍵值對冈涧。Entry包含如下三個方法:

  • Object getKey()
  • Object getValue()
  • Object setValue(V value)

java8新增的方法

  • Object compute(Object key, BiFunction remappingFunction)
  • Object computeIfAbsent(Object key, Function mappingFunction)
  • Object computeIfPresent(Object key, BiFunction remappingFunction)
  • void forEach(BiConsumer action)
  • Object getOrDefault(Object key, V default Value)
  • Object merge(Object key, Object value, BiFunction remappingFunction)
  • Object putIfAbsent(Object key, Object value)
  • Object replace(Object key, Object value)
  • boolean replace(K key, V oldValue, V newValue)
  • replaceA(BiFunction Function)

java8改進的Hash Map和Hashtable實現(xiàn)類

hashtable和vector同一時期出現(xiàn)。

區(qū)別:

  1. Hashtable是線程安全的
  2. Hashtable不允許null作為key和value

用作key的對象必須實現(xiàn)hashcode()和equals()方法

與HashSet類似正蛙,盡量不要使用可變對象作為HashMap、Hashtable的key营曼。

LinkedHashMap

使用雙向鏈表維護key-value對的次序乒验。

使用Properties讀寫屬性文件

Properties是Hashtable的子類。

  • String getProperty(String key)
  • String getProperty(String key, String defaultValue)
  • String setProperty(String key, String value)
  • void load(InputStream inStream)
  • void store(OutputStream out, String comments)

SortedMap接口和TreeMap實現(xiàn)類

Map性能分析

HashMap和Hashtable實現(xiàn)機制相同蒂阱,但由于Hashtable是一個古老的锻全、線程安全的集合,HashMap通常比Hashtable快录煤。

TreeMap更慢鳄厌,但是其key-value是有序狀態(tài),無需專門的排序操作妈踊×撕浚可以調(diào)用keySet(),再用toArray()方法廊营,再用Arrays的binarySearch()方法快速查找對象歪泳。

七、操作集合的工具類Collections

排序

  • void reverse(List list)
  • void shuffle(List list)
  • void sort(List list)
  • void sort(List list, Comparator c)
  • void swap(List list, int i, int j)
  • void rotate(List list, int distance)

查找露筒、替換操作

  • int binarySearch(List list, Object key)
  • Object Max(Collection coll)
  • Object Max(Collection coll, Comparator c)
  • Object Min(Collection coll)
  • Object Min(Collection coll, Comparator c)
  • void fill(List list, Object obj)
  • int frequency(Collection c, Object o)
  • int indexOfSubList(List source, List target)
  • int lastIndexOfSubList(List source, List target)
  • boolean replaceAll(List list, Object oldVal, Object newVal)

同步控制

synchronizaedXxx()方法呐伞。

設(shè)置不可變集合

  • emptyXxx()
  • singletonXxx()
  • unmodifiableXxx()

九、繁瑣的接口Enumeration

該接口是Iterator接口的古老版本慎式。

不要使用伶氢,使用Iterator代替

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瘪吏,隨后出現(xiàn)的幾起案子癣防,更是在濱河造成了極大的恐慌,老刑警劉巖掌眠,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劣砍,死亡現(xiàn)場離奇詭異,居然都是意外死亡扇救,警方通過查閱死者的電腦和手機刑枝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門香嗓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人装畅,你說我怎么就攤上這事靠娱。” “怎么了掠兄?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵像云,是天一觀的道長。 經(jīng)常有香客問我蚂夕,道長迅诬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任婿牍,我火速辦了婚禮侈贷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘等脂。我一直安慰自己俏蛮,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布上遥。 她就那樣靜靜地躺著搏屑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪粉楚。 梳的紋絲不亂的頭發(fā)上辣恋,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音模软,去河邊找鬼抑党。 笑死,一個胖子當著我的面吹牛撵摆,可吹牛的內(nèi)容都是我干的底靠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼特铝,長吁一口氣:“原來是場噩夢啊……” “哼暑中!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鲫剿,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤鳄逾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后灵莲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雕凹,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了枚抵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片线欲。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖汽摹,靈堂內(nèi)的尸體忽然破棺而出李丰,到底是詐尸還是另有隱情,我是刑警寧澤逼泣,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布趴泌,位于F島的核電站,受9級特大地震影響拉庶,放射性物質(zhì)發(fā)生泄漏嗜憔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一氏仗、第九天 我趴在偏房一處隱蔽的房頂上張望吉捶。 院中可真熱鬧,春花似錦廓鞠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至榄审,卻和暖如春砌们,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搁进。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工浪感, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人饼问。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓影兽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親莱革。 傳聞我的和親對象是個殘疾皇子峻堰,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法盅视,內(nèi)部類的語法捐名,繼承相關(guān)的語法,異常的語法闹击,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,254評論 0 16
  • Collection ├List │├LinkedList │├ArrayList │└Vector │└Stac...
    AndyZX閱讀 869評論 0 1
  • java筆記第一天 == 和 equals ==比較的比較的是兩個變量的值是否相等贺归,對于引用型變量表示的是兩個變量...
    jmychou閱讀 1,485評論 0 3
  • 一座寺院淆两,依山傍塬,經(jīng)風見雨牧氮,聳立數(shù)百年琼腔,乍見之,依然恢弘彌新踱葛。 八寶如意塔是釋迦摩尼功德的展示場丹莲,大金瓦殿、大經(jīng)...
    秋水長天白銀閱讀 283評論 0 3