日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

2接口详解_java集合【2】——— Collection接口详解

發(fā)布時(shí)間:2024/8/23 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2接口详解_java集合【2】——— Collection接口详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
  • 一、Collection接口簡(jiǎn)介

  • 二、Collection源碼分析

  • 三、Collection的子類(lèi)以及子類(lèi)的實(shí)現(xiàn)

    • 3.1 List extend Collection

    • 3.2 Set extend Collection

    • 3.3 Queue extend Collection

  • 四、Collection和Map的辨析

  • 五、Collection和Collections的辨析

  • 六、總結(jié)

一、Collection接口簡(jiǎn)介

collection在java集合中,算是頂級(jí)接口,它繼承了iterable接口,不能實(shí)例化,只能實(shí)例化其子類(lèi)。之所以需要這樣一個(gè)接口,是因?yàn)閖ava作為面向?qū)ο?#xff0c;總是避免不了處理多個(gè)對(duì)象的情況,要處理多個(gè)對(duì)象,首先需要容器存儲(chǔ),這個(gè)容器就是集合。為什么有了數(shù)組,還需要集合,因?yàn)閿?shù)組的功能單一,長(zhǎng)度不可變,而有些集合實(shí)現(xiàn)類(lèi)則是對(duì)數(shù)組操作的封裝。

Collection集合和數(shù)組的區(qū)別:

  • 集合長(zhǎng)度可以變,數(shù)組是定長(zhǎng)的
  • 集合存儲(chǔ)的元素只能是引用類(lèi)型,而數(shù)組則可以是基本類(lèi)型
  • 數(shù)組只能執(zhí)行基本操作,而集合功能經(jīng)過(guò)拓展,更加豐富。
graph TD;
Collection -->List-有順序,可重復(fù)
List-有順序,可重復(fù) -->LinkedList-使用鏈表實(shí)現(xiàn),線程不安全
List-有順序,可重復(fù) -->ArrayList-數(shù)組實(shí)現(xiàn),線程不安全
List-有順序,可重復(fù) -->Vector-數(shù)組實(shí)現(xiàn),線程安全
Vector-數(shù)組實(shí)現(xiàn),線程安全 -->Stack-堆棧,先進(jìn)后出

Collection-->Set-不可重復(fù),內(nèi)部排序
Set-不可重復(fù),內(nèi)部排序-->HashSet-hash表存儲(chǔ)
HashSet-hash表存儲(chǔ)-->LinkHashSet-鏈表維護(hù)插入順序
Set-不可重復(fù),內(nèi)部排序-->TreeSet-二叉樹(shù)實(shí)現(xiàn),排序

Collection-->Queue-隊(duì)列,先進(jìn)先出

二、Collection源碼分析

Collection繼承于Iterable接口,而Iterable接口,是集合的頂級(jí)接口,沒(méi)有之一,Iterable接口定義的功能是可以迭代,也就是獲取迭代器iterator的功能,因此Collection以及其實(shí)現(xiàn)類(lèi)也間接獲得迭代的功能。

為什么需要這樣子定義呢?我陷入了深深地思考...?

其實(shí),這也算是哲學(xué)問(wèn)題,java的類(lèi)的設(shè)計(jì)是經(jīng)過(guò)很長(zhǎng)時(shí)間的考驗(yàn)以及調(diào)整形成的,平衡修改以及耦合等各方面的原因,結(jié)構(gòu)更加清晰,維護(hù)成本更低,邏輯性更強(qiáng)。這些接口就是一個(gè)個(gè)標(biāo)準(zhǔn)或者規(guī)范,其子類(lèi)就是不斷拓展功能,這些接口的形成是一種抽象,將能迭代事物抽象成為迭代器iterator,將獲取迭代器,也就是迭代能力抽象成iterable。Collection則是獲得迭代能力的接口之一,其實(shí)Map的實(shí)現(xiàn)類(lèi)里面也是有使用到iterable接口,幾乎所有的集合實(shí)現(xiàn)類(lèi)都是需要遍歷元素的,所以這個(gè)iterable也是必須存在的,存在即合理。

下面看Collection接口以及iterable接口的方法對(duì)比:從上面的圖我們可以看出,iterable接口功能主要是

  • 獲取迭代器iterator
  • foreach()遍歷
  • 獲取可切分迭代器Spliterator

Collection接口在此基礎(chǔ)上進(jìn)行拓展,源碼接口如下:

boolean?add(Object?o)????//添加元素boolean?remove(Object?o)??//移除元素boolean?addAll(Collection?c)?//批量添加boolean?removeAll(Collection?c)??//批量移除void?retainAll(Collection?c)???//?移除在c中不存在的元素void?clear()??//清空集合int?size()???//集合大小boolean?isEmpty()????//是否為空boolean?contains(Object?o)????//是否包含在集合中boolean?containsAll(Collection?c)????//是否包含所有的元素
Iterator?iterator()????//?獲取迭代器
Object[]?toArray()???//?轉(zhuǎn)成數(shù)組default?boolean?removeIf(Predicate?super?E>?filter)?{}?//?刪除集合中復(fù)合條件的元素,刪除成功返回true

boolean?equals(Object?o)int?hashCode()default?Spliterator?spliterator()?{}?//獲取可分割迭代器

default?Stream?stream()?{}???//獲取流

default?Stream?parallelStream()?{}?//獲取并行流

里面獲取并行流的方法parallelStream(),其實(shí)就是通過(guò)默認(rèn)的ForkJoinPool(主要用來(lái)使用分治法(Divide-and-Conquer Algorithm)來(lái)解決問(wèn)題),提高多線程任務(wù)的速度。我們可以使用ArrayList來(lái)演示一下平行處理能力。例如下面的例子,輸出的順序就不一定是1,2,3...,可能是亂序的,這是因?yàn)槿蝿?wù)會(huì)被分成多個(gè)小任務(wù),任務(wù)執(zhí)行是沒(méi)有特定的順序的。

List?list?=?Arrays.asList(1,?2,?3,?4,?5,?6,?7,?8,?9);
list.parallelStream()
???????.forEach(out::println);

上面源代碼可以看出,Collection接口定義了功能規(guī)范,有以下功能方法:

  • 添加元素
  • 刪除元素
  • 判斷是否包含/是否全部包含/是否為空
  • 獲取迭代器/可分割迭代器
  • 獲取長(zhǎng)度
  • 取交集
  • 獲取流/并行流

我們遍歷元素的時(shí)候可以獲取Iterator,但是具體的實(shí)現(xiàn)是以子類(lèi)的特性去實(shí)現(xiàn)的,比如ArrayList是用內(nèi)部類(lèi)的方式實(shí)現(xiàn)了Iterator接口。

三、Collection的子類(lèi)以及子類(lèi)的實(shí)現(xiàn)

繼承Collection的子類(lèi)關(guān)系如下:

上面的類(lèi)圖已經(jīng)足夠清楚,下面是一些簡(jiǎn)單的概括(上面的類(lèi)型是使用IDEA的類(lèi)圖功能自動(dòng)生成,簡(jiǎn)直不能太好用???感覺(jué)發(fā)現(xiàn)了新大陸)

3.1 List extend Collection

繼承于Collection接口,有順序,取出的順序與存入的順序一致,有索引,可以根據(jù)索引獲取數(shù)據(jù),允許存儲(chǔ)重復(fù)的元素,可以放入為null的元素。
最常見(jiàn)的三個(gè)實(shí)現(xiàn)類(lèi)就是ArrayList,Vector,LinkedList,ArrayList和Vector都是內(nèi)部封裝了對(duì)數(shù)組的操作,唯一不同的是,Vector是線程安全的,而ArrayList不是,理論上ArrayList操作的效率會(huì)比Vector好一些。

里面是接口定義的方法:

int?size();??//獲取大小

boolean?isEmpty();??//判斷是否為空

boolean?contains(Object?o);??//是否包含某個(gè)元素

Iterator?iterator();?//獲取迭代器

Object[]?toArray();??//?轉(zhuǎn)化成為數(shù)組(對(duì)象)

?T[]?toArray(T[]?a);??//?轉(zhuǎn)化為數(shù)組(特定位某個(gè)類(lèi))boolean?add(E?e);?//添加boolean?remove(Object?o);??//移除元素boolean?containsAll(Collection>?c);?//?是否包含所有的元素boolean?addAll(Collection?extends?E>?c);?//批量添加boolean?addAll(int?index,?Collection?extends?E>?c);?//批量添加,指定開(kāi)始的索引boolean?removeAll(Collection>?c);?//批量移除boolean?retainAll(Collection>?c);?//將c中不包含的元素移除default?void?replaceAll(UnaryOperator?operator)?{}//替換default?void?sort(Comparator?super?E>?c)?{}//?排序void?clear();//清除所有的元素boolean?equals(Object?o);//是否相等int?hashCode();?//計(jì)算獲取hash值E?get(int?index);?//通過(guò)索引獲取元素E?set(int?index,?E?element);//修改元素void?add(int?index,?E?element);//在指定位置插入元素E?remove(int?index);//根據(jù)索引移除某個(gè)元素int?indexOf(Object?o);??//根據(jù)對(duì)象獲取索引int?lastIndexOf(Object?o);?//獲取對(duì)象元素的最后一個(gè)元素ListIterator?listIterator();?//?獲取List迭代器ListIterator?listIterator(int?index);?//?根據(jù)索引獲取當(dāng)前的位置的迭代器List?subList(int?fromIndex,?int?toIndex);?//截取某一段數(shù)據(jù)default?Spliterator?spliterator(){}?//獲取可切分迭代器

上面的方法都比較簡(jiǎn)單,值得一提的是里面出現(xiàn)了ListIterator,這是一個(gè)功能更加強(qiáng)大的迭代器,繼承于Iterator,只能用于List類(lèi)型的訪問(wèn),拓展功能例如:通過(guò)調(diào)用listIterator()方法獲得一個(gè)指向List開(kāi)頭的ListIterator,也可以調(diào)用listIterator(n)獲取一個(gè)指定索引為n的元素的ListIterator,這是一個(gè)可以雙向移動(dòng)的迭代器。
操作數(shù)組索引的時(shí)候需要注意,由于List的實(shí)現(xiàn)類(lèi)底層很多都是數(shù)組,所以索引越界會(huì)報(bào)錯(cuò)IndexOutOfBoundsException。
說(shuō)起List的實(shí)現(xiàn)子類(lèi):

  • ArrayList:底層存儲(chǔ)結(jié)構(gòu)是數(shù)組結(jié)構(gòu),增加刪除比較慢,查找比較快,是最常用的List集合。線程不安全。
  • LinkedList:底層是鏈表結(jié)構(gòu),增加刪除比較快,但是查找比較慢。線程不安全。
  • Vector:和ArrayList差不多,但是是線程安全的,即同步。

3.2 Set extend Collection

Set接口,不允許放入重復(fù)的元素,也就是如果相同,則只存儲(chǔ)其中一個(gè)。

下面是源碼方法:

int?size();?//獲取大小

boolean?isEmpty();??//是否為空
?
boolean?contains(Object?o);?//是否包含某個(gè)元素

Iterator?iterator();?//獲取迭代器

Object[]?toArray();?//轉(zhuǎn)化成為數(shù)組

?T[]?toArray(T[]?a);?//轉(zhuǎn)化為特定類(lèi)的數(shù)組boolean?add(E?e);???//添加元素boolean?remove(Object?o);???//移除元素boolean?containsAll(Collection>?c);???//是否包含所有的元素boolean?addAll(Collection?extends?E>?c);??//批量添加boolean?retainAll(Collection>?c);?//移除所有不存在于c集合中的元素boolean?removeAll(Collection>?c);?//移除所有在c集合中存在的元素void?clear();???//清空集合boolean?equals(Object?o);???//是否相等int?hashCode();?//計(jì)算hashcodedefault?Spliterator?spliterator()?{}?????//獲取可分割迭代器

主要的子類(lèi):

  • HashSet
    • 允許空值
    • 通過(guò)HashCode方法計(jì)算獲取hash值,確定存儲(chǔ)位置,無(wú)序。
    • 底層是哈希表,一個(gè)元素為鏈表的數(shù)組
  • LinkedHashSet
    • HashSet的子類(lèi)
    • 有順序
    • 底層由哈希表組成
  • TreeSet
    • 如果無(wú)參數(shù)構(gòu)建Set,則需要實(shí)現(xiàn)Comparable方法。
    • 亦可以創(chuàng)建時(shí)傳入比較方法,用于排序。

3.3 Queue extend Collection

隊(duì)列接口,在Collection接口的接觸上添加了增刪改查接口定義,一般默認(rèn)是先進(jìn)先出,即FIFO,除了優(yōu)先隊(duì)列和棧,優(yōu)先隊(duì)列是自己定義了排序的優(yōu)先順序,隊(duì)列中不允許放入null元素。

下面是源碼:

boolean?add(E?e);???//插入一個(gè)元素到隊(duì)列,失敗時(shí)返回IllegalStateException?(如果隊(duì)列容量不夠)

boolean?offer(E?e);?//插入一個(gè)元素到隊(duì)列,失敗時(shí)返回false

E?remove();?//移除隊(duì)列頭的元素并移除

E?poll();???//返回并移除隊(duì)列的頭部元素,隊(duì)列為空時(shí)返回null

E?element();????//返回隊(duì)列頭元素

E?peek();???//返回隊(duì)列頭部的元素,隊(duì)列為空時(shí)返回null

主要的子接口以及實(shí)現(xiàn)類(lèi)有:

  • Deque(接口):Queue的子接口,雙向隊(duì)列,可以從兩邊存取
    • ArrayDeque:Deque的實(shí)現(xiàn)類(lèi),底層用數(shù)組實(shí)現(xiàn),數(shù)據(jù)存貯在數(shù)組中
  • AbstractQueue:Queue的子接口,僅實(shí)現(xiàn)了add、remove和element三個(gè)方法
    • PriorityQueue:按照默認(rèn)或者自己定義的順序來(lái)排序元素,底層使用堆(完全二叉樹(shù))實(shí)現(xiàn),使用動(dòng)態(tài)數(shù)組實(shí)現(xiàn),
  • BlockingQueue:在java.util.concurrent包中,阻塞隊(duì)列,滿足當(dāng)前無(wú)法處理的操作。

對(duì)于Collection集合我們應(yīng)該使用哪一個(gè)?

每個(gè)實(shí)現(xiàn)都有自己的特點(diǎn),重要的是知道當(dāng)前數(shù)據(jù)以及業(yè)務(wù)的特點(diǎn),選取最適合的集合類(lèi)進(jìn)行數(shù)據(jù)操作。

  • 元素唯一(Set)
    • 唯一,有序 (自定義排序):TreeSet(速度較慢)
    • FIFO,按照插入順序,唯一:LinkedHashSet(速度較快)
    • 需要排序
    • 不需要排序:HashSet(速度最快)
  • 元素唯一
    • 普通排隊(duì) :Queue的子類(lèi)
    • 兩端都可以排隊(duì):ArrayDeque
    • 按照自己定義的規(guī)則排序:PriorityQueue
    • 處理排隊(duì)當(dāng)前無(wú)法處理太多請(qǐng)求(相當(dāng)于緩沖):阻塞隊(duì)列接口BlockingQueue
    • 線程安全:Vector
    • 接受線程不安全
    • 查詢比較多:ArrayList
    • 增加刪除操作較多:LinkedList
    • 列表:List
    • 排隊(duì)

四、Collection和Map的辨析

  • Collection接口是存儲(chǔ)單列元素,而Map是鍵值對(duì),也就是存儲(chǔ)了雙列元素。
  • Collection接口繼承了Iterable接口,而Map則不是,Map是在各自的實(shí)現(xiàn)類(lèi)中才用內(nèi)部類(lèi)的方式實(shí)現(xiàn)Iterator接口,例如HashMap,key或者value或者它們的組合entry都可以使用迭代器進(jìn)行遍歷。
  • 兩個(gè)的子類(lèi)其實(shí)是有交集的,比如HashSet的底層實(shí)現(xiàn)其實(shí)就是定義了一個(gè)HashMap,TreeSet同樣依賴于Map接口的子實(shí)現(xiàn)類(lèi)TreeMap。

Map集合可以存儲(chǔ)鍵值對(duì),可以獲取所有的鍵,或者值或者鍵值對(duì),鍵不允許重復(fù),但是值可以重復(fù)。隨便說(shuō)說(shuō)Map相關(guān)的子類(lèi):

  • HashTable:
    • 源于JDK1.1,底層使用數(shù)組和鏈表
    • 線程安全,不允許null作為key或者value
  • HashMap:
    • 源于JDK1.2,JDK1.7以及之前使用數(shù)組+鏈表實(shí)現(xiàn),JDK1.8使用數(shù)組+鏈表/紅黑樹(shù)
    • 線程不安全
  • LinkedHashMap:
    • 保存了插入的順序,可以按照順序遍歷
  • TreeMap:
    • 實(shí)現(xiàn)了SortMap接口,可以把保存的記錄按照鍵排序
    • 底層是用紅黑樹(shù)實(shí)現(xiàn)

五、Collection和Collections的辨析

(1).Collection是集合的頂級(jí)接口之一,衍生出了Set,List,Queue等一系列接口以及實(shí)現(xiàn)類(lèi)。而Collections是一個(gè)輔助類(lèi),就是實(shí)現(xiàn)一些排序,搜索,線程安全等功能,它主要體現(xiàn)的功能是操作集合,而Collection則是集合本身。

(2).Collection是接口,其本身不能實(shí)例化,但是可以實(shí)例化為其子類(lèi)或者實(shí)現(xiàn)類(lèi),但是Collections是包裝類(lèi),一般不會(huì)實(shí)例化,直接調(diào)用static方法。

Collections接口主要提供了以下操作,只展示了部分,詳細(xì)需要后面文章說(shuō):

  • Sort(排序):public static > void sort(List list),元素需要實(shí)現(xiàn)Comparable接口,按照比較器進(jìn)行排序。
  • binarySearch(二分搜索):public static int binarySearch(List extends Comparable super T>> list, T key),
  • reverse(反轉(zhuǎn)):public static void reverse(List> list)反轉(zhuǎn)順序
  • Shuffling(混排):public static void shuffle(List> list),將list的元素隨機(jī)打亂。
  • 交換(swap):public static void swap(List> list, int i, int j)交換兩個(gè)索引的元素
  • 拷貝(copy):public static void copy(List super T> dest, List extends T> src),copy出一個(gè)內(nèi)容一致的list。
  • 返回最小的元素(min):所謂大小,根據(jù)指定的比較器決定,static > T min(Collection extends T> coll)
  • 返回最大的元素(max):static > T max(Collection extends T> coll)
  • 旋轉(zhuǎn)(Rotate):將一個(gè)List旋轉(zhuǎn),假如有個(gè)序列列l(wèi)ist是[1,2,3,4],調(diào)用方法Collections.rotate(list, 1)后,得到list就變成[4,1,2,3],public static void rotate(List> list, int distance)
  • 替換所有元素(replaceAll):public static boolean replaceAll(List list, T oldVal, T newVal)
  • 獲取元素出現(xiàn)最后的索引(lastIndexOfSubList):public static int lastIndexOfSubList(List> source, List> target)
  • 六、總結(jié)

    Collection接口繼承了iterable接口,是集合的頂級(jí)接口之一,衍生接口有List,Set,Queue等,主要定義了元素的基本操作,刪除,添加等等方法,迭代一個(gè)Collection可以使用Iterator,但是Collection本身不能實(shí)例化。

    - END -

    總結(jié)

    以上是生活随笔為你收集整理的2接口详解_java集合【2】——— Collection接口详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。