<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          集合框架大管家

          共 5607字,需瀏覽 12分鐘

           ·

          2021-10-25 23:35

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

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

          https://github.com/itwanger/toBeBetterJavaer

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

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

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

          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):使用指定對象填充
          • frequency(Collection c, Object o):返回指定對象出現(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 是線程不安全的,這個我們前面講到了。那其實 ArrayList 也是線程不安全的,沒法在多線程環(huán)境下使用,那 Collections 工具類中提供了多個 synchronizedXxx 方法,這些方法會返回一個同步的對象,從而解決多線程中訪問集合時的安全問題。

          使用起來也非常的簡單:

          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);}
          ????}
          }

          那這樣的話,其實效率和那些直接在方法上加 synchronized 關(guān)鍵字的 Vector、Hashtable 差不多(JDK 1.0 時期就有了),而這些集合類基本上已經(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ā)編程時再講。

          04、不可變集合

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

          舉個例子:

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

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

          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)

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

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

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

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

          05、其他

          還有兩個方法比較常用:

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

          舉個例子:

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

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

          輸出后:

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

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

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

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

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

          這才是高手要思考的一個問題。

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

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

          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色秘 乱码一区二区三区唱戏 | av色先锋 | 午夜高清性爱视频 | 2024亚洲有码无码中文字幕 | 99热网址 |