JDK Collections工具類

起因:工作中需要對(duì)集合進(jìn)行一個(gè)亂序的重排序,當(dāng)時(shí)不太記得Collections中的方法,去百度了一下,發(fā)現(xiàn)Collections工具類提供了相應(yīng)的方法陕截,之前有用過(guò)Collections其中的一些方法,但是沒(méi)有對(duì)其API有一個(gè)系統(tǒng)的學(xué)習(xí)和記錄批什,這次記錄一下农曲。知道這里有了,用的時(shí)候也好找了驻债。

Collections是 JDK提供的工具類乳规,提供了一系列靜態(tài)方法,方便操作各種集合合呐。分析和總結(jié)一下其API暮的,記錄一下。

Collections主要有以下幾個(gè)功能

  • 排序
  • 亂序(洗牌)
  • 替換
  • 創(chuàng)建空集合
  • 創(chuàng)建單元集合
  • 不可變集合
  • 線程安全集合

接下來(lái)稍微介紹一下相關(guān)操作與demo淌实,其實(shí)看api更好冻辩。

1.排序

  • reverse(List list):反轉(zhuǎn)指定List集合中元素的順序
  • shuffle(List list):對(duì)List中的元素進(jìn)行隨機(jī)排序(洗牌)
  • sort(List list):對(duì)List里的元素根據(jù)自然升序排序
  • sort(List list, Comparator c):自定義比較器進(jìn)行排序
  • swap(List list, int i, int j):將指定List集合中i處元素和j出元素進(jìn)行交換
  • rotate(List list, int distance):將所有元素向右移位指定長(zhǎng)度,如果distance等于size那么結(jié)果不變

Collections可以對(duì)List進(jìn)行sort排序拆祈。因?yàn)榕判驎?huì)直接修改List元素的位置恨闪,因此必須傳入可變List。

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("pear");
        list.add("orange");
        // 排序前:
        System.out.println(list);
        Collections.sort(list);
        // 排序后:
        System.out.println(list);
    }

排序也是有講究的放坏。列表中的所有元素必須實(shí)現(xiàn)Comparable接口,因?yàn)樽罱K還是要根據(jù)Comparable中的方法來(lái)對(duì)其實(shí)施排序咙咽。以下是JDK源碼。
除了默認(rèn)排序還有自定義排序淤年,自定義排序需要傳入Comparator比較器犁珠。一般使用compare(T o1, T o2)方法就可以了,比較常用的還有reversed()方法互亮,到排序。詳情見(jiàn)我的另一篇余素,排序豹休!

//默認(rèn)排序    
    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }
//自定義排序
    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
    }

2.亂序(洗牌)

Collections提供了洗牌算法,即傳入一個(gè)有序的List桨吊,可以隨機(jī)打亂List內(nèi)部元素的順序威根,效果相當(dāng)于讓計(jì)算機(jī)洗牌:

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i=0; i<10; i++) {
            list.add(i);
        }
        // 洗牌前:
        System.out.println(list);
        Collections.shuffle(list);
        // 洗牌后:
        System.out.println(list);
    }

排序其實(shí)就是拿到傳入的list凤巨,然后對(duì)任意兩個(gè)元素交換位置,也可以傳入一個(gè)帶隨機(jī)數(shù)的洛搀,沒(méi)看源碼敢茁,有空可以了解一下。

    public static void shuffle(List<?> list) {
        Random rnd = r;
        if (rnd == null)
            r = rnd = new Random(); // harmless race.
        shuffle(list, rnd);
    }

    private static Random r;
//--------------------------------------
    public static void shuffle(List<?> list, Random rnd) {
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=size; i>1; i--)
                swap(list, i-1, rnd.nextInt(i));
        } else {
            Object arr[] = list.toArray();

            // Shuffle array
            for (int i=size; i>1; i--)
                swap(arr, i-1, rnd.nextInt(i));

            // Dump array back into list
            // instead of using a raw type here, it's possible to capture
            // the wildcard but it will require a call to a supplementary
            // private method
            ListIterator it = list.listIterator();
            for (int i=0; i<arr.length; i++) {
                it.next();
                it.set(arr[i]);
            }
        }
    }
//--------------------------------------
    private static void swap(Object[] arr, int i, int j) {
        Object tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

3. 查找和替換

  • binarySearch(List list, Object key):使用二分搜索法留美,以獲得指定對(duì)象在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 Object o):返回指定集合中指定對(duì)象出現(xiàn)的次數(shù)
  • replaceAll(List list, Object old, Object new):替換

4.創(chuàng)建空集合

Collections提供了一系列方法來(lái)創(chuàng)建空集合:
創(chuàng)建空List:List<T> emptyList()
創(chuàng)建空Map:Map<K, V> emptyMap()
創(chuàng)建空Set:Set<T> emptySet()
要注意到返回的空集合是不可變集合逢倍,無(wú)法向其中添加或刪除元素。

此外景图,也可以用各個(gè)集合接口提供的of(T...)方法創(chuàng)建空集合较雕。例如,以下創(chuàng)建空List的兩個(gè)方法是等價(jià)的:

List<String> list1 = List.of();
List<String> list2 = Collections.emptyList();

創(chuàng)建新的集合現(xiàn)在都在用Guava 的Lists.asList(),之后再記錄一下

  public static <E> List<E> asList(@Nullable E first, E[] rest) {
    return new OnePlusArrayList<E>(first, rest);
  }

5.創(chuàng)建單元素集合

Collections提供了一系列方法來(lái)創(chuàng)建一個(gè)單元素集合:

創(chuàng)建一個(gè)元素的List:List<T> singletonList(T o)
創(chuàng)建一個(gè)元素的Map:Map<K, V> singletonMap(K key, V value)
創(chuàng)建一個(gè)元素的Set:Set<T> singleton(T o)
要注意到返回的單元素集合也是不可變集合挚币,無(wú)法向其中添加或刪除元素亮蒋。

此外,也可以用各個(gè)集合接口提供的of(T...)方法創(chuàng)建單元素集合妆毕。例如慎玖,以下創(chuàng)建單元素List的兩個(gè)方法是等價(jià)的:

List<String> list1 = List.of("apple");
List<String> list2 = Collections.singletonList("apple");

實(shí)際上,使用List.of(T...)更方便设塔,因?yàn)樗瓤梢詣?chuàng)建空集合凄吏,也可以創(chuàng)建單元素集合,還可以創(chuàng)建任意個(gè)元素的集合:

List<String> list1 = List.of(); // empty list
List<String> list2 = List.of("apple"); // 1 element
List<String> list3 = List.of("apple", "pear"); // 2 elements
List<String> list4 = List.of("apple", "pear", "orange"); // 3 elements

6.不可變集合

Collections還提供了一組方法把可變集合封裝成不可變集合:

封裝成不可變List:List<T> unmodifiableList(List<? extends T> list)
封裝成不可變Set:Set<T> unmodifiableSet(Set<? extends T> set)
封裝成不可變Map:Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m)
這種封裝實(shí)際上是通過(guò)創(chuàng)建一個(gè)代理對(duì)象闰蛔,攔截掉所有修改方法實(shí)現(xiàn)的痕钢。類似與Guava 的ImmutableMap我的另一篇Guava 的ImmutableMap

7.線程安全集合

自從有了juc,基本沒(méi)啥用序六,就不寫了任连。

不要以為每天把功能完成了就行了,這種思想是要不得的例诀,互勉~随抠!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市繁涂,隨后出現(xiàn)的幾起案子拱她,更是在濱河造成了極大的恐慌,老刑警劉巖扔罪,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秉沼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)唬复,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門矗积,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人敞咧,你說(shuō)我怎么就攤上這事棘捣。” “怎么了休建?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵乍恐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我丰包,道長(zhǎng)禁熏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任邑彪,我火速辦了婚禮瞧毙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寄症。我一直安慰自己宙彪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布有巧。 她就那樣靜靜地躺著释漆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪篮迎。 梳的紋絲不亂的頭發(fā)上男图,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音甜橱,去河邊找鬼逊笆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛岂傲,可吹牛的內(nèi)容都是我干的难裆。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼镊掖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乃戈!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起亩进,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤症虑,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后归薛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谍憔,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驶冒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了韵卤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡崇猫,死狀恐怖沈条,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诅炉,我是刑警寧澤蜡歹,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站涕烧,受9級(jí)特大地震影響月而,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜议纯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一父款、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞻凤,春花似錦憨攒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蛛壳,卻和暖如春杏瞻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衙荐。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工捞挥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赫模。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓树肃,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瀑罗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子胸嘴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350