1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        集合框架大管家

        共 5607字,需瀏覽 12分鐘

         ·

        2021-10-25 23:35

        Collections 是 JDK 提供的一個(gè)工具類,位于 java.util 包下,提供了一系列的靜態(tài)方法,方便我們對(duì)集合進(jìn)行各種騷操作,算是集合框架的一個(gè)大管家。

        PS:star 這種事,只能求,不求沒效果,鐵子們,《Java 程序員進(jìn)階之路》在 GitHub 上已經(jīng)收獲了 455 枚星標(biāo),鐵子們趕緊去點(diǎn)點(diǎn)了,沖 500 star!

        https://github.com/itwanger/toBeBetterJavaer

        還記得我們前面講過的 Arrays 工具類嗎?可以回去溫習(xí)下。

        Collections 的用法很簡(jiǎn)單,在 Intellij IDEA 中敲完 Collections. 之后就可以看到它提供的方法了,大致看一下方法名和參數(shù)就能知道這個(gè)方法是干嘛的。

        為了節(jié)省大家的學(xué)習(xí)時(shí)間,我將這些方法做了一些分類,并列舉了一些簡(jiǎn)單的例子。

        01、排序操作

        • reverse(List list):反轉(zhuǎn)順序
        • shuffle(List list):洗牌,將順序打亂
        • sort(List list):自然升序
        • sort(List list, Comparator c):按照自定義的比較器排序
        • swap(List list, int i, int j):將 i 和 j 位置的元素交換位置

        來看例子:

        List?list?=?new?ArrayList<>();
        list.add("沉默王二");
        list.add("沉默王三");
        list.add("沉默王四");
        list.add("沉默王五");
        list.add("沉默王六");

        System.out.println("原始順序:"?+?list);

        //?反轉(zhuǎn)
        Collections.reverse(list);
        System.out.println("反轉(zhuǎn)后:"?+?list);

        //?洗牌
        Collections.shuffle(list);
        System.out.println("洗牌后:"?+?list);

        //?自然升序
        Collections.sort(list);
        System.out.println("自然升序后:"?+?list);

        //?交換
        Collections.swap(list,?2,4);
        System.out.println("交換后:"?+?list);

        輸出后:

        原始順序:[沉默王二, 沉默王三, 沉默王四, 沉默王五, 沉默王六]
        反轉(zhuǎn)后:[沉默王六, 沉默王五, 沉默王四, 沉默王三, 沉默王二]
        洗牌后:[沉默王五, 沉默王二, 沉默王六, 沉默王三, 沉默王四]
        自然升序后:[沉默王三, 沉默王二, 沉默王五, 沉默王六, 沉默王四]
        交換后:[沉默王三, 沉默王二, 沉默王四, 沉默王六, 沉默王五]

        02、查找操作

        • binarySearch(List list, Object key):二分查找法,前提是 List 已經(jīng)排序過了
        • max(Collection coll):返回最大元素
        • max(Collection coll, Comparator comp):根據(jù)自定義比較器,返回最大元素
        • min(Collection coll):返回最小元素
        • min(Collection coll, Comparator comp):根據(jù)自定義比較器,返回最小元素
        • fill(List list, Object obj):使用指定對(duì)象填充
        • frequency(Collection c, Object o):返回指定對(duì)象出現(xiàn)的次數(shù)

        來看例子:

        System.out.println("最大元素:"?+?Collections.max(list));
        System.out.println("最小元素:"?+?Collections.min(list));
        System.out.println("出現(xiàn)的次數(shù):"?+?Collections.frequency(list,?"沉默王二"));

        //?沒有排序直接調(diào)用二分查找,結(jié)果是不確定的
        System.out.println("排序前的二分查找結(jié)果:"?+?Collections.binarySearch(list,?"沉默王二"));
        Collections.sort(list);
        //?排序后,查找結(jié)果和預(yù)期一致
        System.out.println("排序后的二分查找結(jié)果:"?+?Collections.binarySearch(list,?"沉默王二"));

        Collections.fill(list,?"沉默王八");
        System.out.println("填充后的結(jié)果:"?+?list);

        輸出后:

        原始順序:[沉默王二, 沉默王三, 沉默王四, 沉默王五, 沉默王六]
        最大元素:沉默王四
        最小元素:沉默王三
        出現(xiàn)的次數(shù):1
        排序前的二分查找結(jié)果:0
        排序后的二分查找結(jié)果:1
        填充后的結(jié)果:[沉默王八, 沉默王八, 沉默王八, 沉默王八, 沉默王八]

        03、同步控制

        HashMap 是線程不安全的,這個(gè)我們前面講到了。那其實(shí) ArrayList 也是線程不安全的,沒法在多線程環(huán)境下使用,那 Collections 工具類中提供了多個(gè) synchronizedXxx 方法,這些方法會(huì)返回一個(gè)同步的對(duì)象,從而解決多線程中訪問集合時(shí)的安全問題。

        使用起來也非常的簡(jiǎn)單:

        SynchronizedList?synchronizedList?=?Collections.synchronizedList(list);

        看一眼 SynchronizedList 的源碼就明白了,不過是在方法里面使用 synchronized 關(guān)鍵字加了一層鎖而已。

        static?class?SynchronizedList<E>
        ????extends?SynchronizedCollection<E>
        ????implements?List<E>?
        {
        ????private?static?final?long?serialVersionUID?=?-7754090372962971524L;

        ????final?List?list;

        ????SynchronizedList(List?list)?{
        ????????super(list);
        ????????this.list?=?list;
        ????}

        ????public?E?get(int?index)?{
        ????????synchronized?(mutex)?{return?list.get(index);}
        ????}
        ????
        ????public?void?add(int?index,?E?element)?{
        ????????synchronized?(mutex)?{list.add(index,?element);}
        ????}
        ????public?E?remove(int?index)?{
        ????????synchronized?(mutex)?{return?list.remove(index);}
        ????}
        }

        那這樣的話,其實(shí)效率和那些直接在方法上加 synchronized 關(guān)鍵字的 Vector、Hashtable 差不多(JDK 1.0 時(shí)期就有了),而這些集合類基本上已經(jīng)廢棄了,幾乎不怎么用。

        public?class?Vector<E>
        ????extends?AbstractList<E>
        ????implements?List<E>,?RandomAccess,?Cloneable,?java.io.Serializable
        {

        ????public?synchronized?E?get(int?index)?{
        ????????if?(index?>=?elementCount)
        ????????????throw?new?ArrayIndexOutOfBoundsException(index);

        ????????return?elementData(index);
        ????}

        ????public?synchronized?E?remove(int?index)?{
        ????????modCount++;
        ????????if?(index?>=?elementCount)
        ????????????throw?new?ArrayIndexOutOfBoundsException(index);
        ????????E?oldValue?=?elementData(index);

        ????????int?numMoved?=?elementCount?-?index?-?1;
        ????????if?(numMoved?>?0)
        ????????????System.arraycopy(elementData,?index+1,?elementData,?index,
        ?????????????????????????????numMoved);
        ????????elementData[--elementCount]?=?null;?//?Let?gc?do?its?work

        ????????return?oldValue;
        ????}
        }

        正確的做法是使用并發(fā)包下的 CopyOnWriteArrayList、ConcurrentHashMap。這些我們放到并發(fā)編程時(shí)再講。

        04、不可變集合

        • emptyXxx():制造一個(gè)空的不可變集合
        • singletonXxx():制造一個(gè)只有一個(gè)元素的不可變集合
        • unmodifiableXxx():為指定集合制作一個(gè)不可變集合

        舉個(gè)例子:

        List?emptyList?=?Collections.emptyList();
        emptyList.add("非空");
        System.out.println(emptyList);

        這段代碼在執(zhí)行的時(shí)候就拋出錯(cuò)誤了。

        Exception?in?thread?"main"?java.lang.UnsupportedOperationException
        ?at?java.util.AbstractList.add(AbstractList.java:148)
        ?at?java.util.AbstractList.add(AbstractList.java:108)
        ?at?com.itwanger.s64.Demo.main(Demo.java:61)

        這是因?yàn)?Collections.emptyList() 會(huì)返回一個(gè) Collections 的內(nèi)部類 EmptyList,而 EmptyList 并沒有重寫父類 AbstractList 的 add(int index, E element) 方法,所以執(zhí)行的時(shí)候就拋出了不支持該操作的 UnsupportedOperationException 了。

        這是從分析 add 方法源碼得出的原因。除此之外,emptyList 方法是 final 的,返回的 EMPTY_LIST 也是 final 的,種種跡象表明 emptyList 返回的就是不可變對(duì)象,沒法進(jìn)行增傷改查。

        public?static?final??List?emptyList()?{
        ????return?(List)?EMPTY_LIST;
        }

        public?static?final?List?EMPTY_LIST?=?new?EmptyList<>();

        05、其他

        還有兩個(gè)方法比較常用:

        • addAll(Collection c, T... elements),往集合中添加元素
        • disjoint(Collection c1, Collection c2),判斷兩個(gè)集合是否沒有交集

        舉個(gè)例子:

        List?allList?=?new?ArrayList<>();
        Collections.addAll(allList,?"沉默王九","沉默王十","沉默王二");
        System.out.println("addAll 后:"?+?allList);

        System.out.println("是否沒有交集:"?+?(Collections.disjoint(list,?allList)???"是"?:?"否"));

        輸出后:

        原始順序:[沉默王二, 沉默王三, 沉默王四, 沉默王五, 沉默王六]
        addAll 后:[沉默王九, 沉默王十, 沉默王二]
        是否沒有交集:否

        整體上,Collections 工具類作為集合框架的大管家,提供了一些非常便利的方法供我們調(diào)用,也非常容易掌握,沒什么難點(diǎn),看看方法的注釋就能大致明白干嘛的。

        不過,工具就放在那里,用是一回事,為什么要這么用就是另外一回事了。能不能提高自己的編碼水平,很大程度上取決于你到底有沒有去鉆一鉆源碼,看這些設(shè)計(jì) JDK 的大師們是如何寫代碼的,學(xué)會(huì)一招半式,在工作當(dāng)中還是能很快脫穎而出的。

        恐怕 JDK 的設(shè)計(jì)者是這個(gè)世界上最好的老師了,文檔寫得不能再詳細(xì)了,代碼寫得不能再優(yōu)雅了,基本上都達(dá)到了性能上的極致。

        可能有人會(huì)說,工具類沒什么鳥用,不過是調(diào)用下方法而已,但這就大錯(cuò)特錯(cuò)了:如果要你來寫,你能寫出來 Collections 這樣一個(gè)工具類嗎?

        這才是高手要思考的一個(gè)問題。

        這是《Java 程序員進(jìn)階之路》專欄的第 64 篇。Java 程序員進(jìn)階之路,風(fēng)趣幽默、通俗易懂,對(duì) Java 初學(xué)者極度友好和舒適??,內(nèi)容包括但不限于 Java 語法、Java 集合框架、Java IO、Java 并發(fā)編程、Java 虛擬機(jī)等核心知識(shí)點(diǎn)。

        點(diǎn)擊上方名片,發(fā)送消息「03」 就可以獲取《Java 程序員進(jìn)階之路》的 PDF 版了,一起成為更好的 Java 工程師。

        瀏覽 45
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            特级婬片A片AAA毛片啪啪声 | 极品美女一区 | 亚洲一级二级三级 | 婷婷五月丁香在线 | 草逼色 | 91亚洲精品国偷拍自产在线视频 | 女人天堂网av | 一区二区三区人妻精品 | 尻屄大全| 日韩mv欧美mv国产网站 |