同事說會寫Java,不一定會用Collections,你會用嗎?

2021-01-07 程序猿的內心獨白

前言

今天和同事聊天,同事說好多人都說自己是java高級程式設計師,結果問一個 Collections的用法,他沉默了。

我說這不能怪他啊,我們是人,我們學習到的知識可能會忘掉,有可能以前知道,過了一段時間就全忘了。

所以,今天我們就來聊聊Collections。

Collections

Collections是Java官方提供的針對集合類的工具類,也是在開發中的一把利刃,能幫我們解決很多開發中的問題,但是依然有很多人不會它的用法,一起來學習一下吧。

Collectors,Collection,Collections

這三兄弟有什麼區別呢:

1.Collectors 主要是用在java stream 中,是用來最後處理stream的,比如 Collectors.toSet()。2.Collection 是所有集合類的接口類,比如常用的Set,List,Map。3.Collections 是Java官方的提供的工具類,今天重點來講一下。 小技巧:可以根據單詞來記憶,Collectors 收集器。Collection 集合 。Collections 一堆集合操作。

Collections中API的分類

排序操作

static <T>boolean addAIl(Collection <? super T>c,T... elements)將所有指定元素添加到指定的collection中static void reverse(List list) 反轉指定List集合中元素的順序static void shuffle(List list)對List集合中的元素進行隨機排序(模擬玩撲克中的「洗牌」)static void sort(List list)根據元素的自然順序對List集合中的元素進行排序static void swap(List list,int i,int j) 將指定List集合中i處元素和j處元素進行交換以上都比較簡單,在用的時候看一下就會明白

查找替換

static int binaryScarch ( List list,Object key)使用二分法搜索指定對象在List集合中的索引,查找的 List集合中的元素必須是有序的static Object max(Collection col)返回給定集合中最大的元素static Object min (Collection col)返回給定集合中最小的元素static boolean replaccAll (List list,Object oldVal,Object newVal)用一個新的newVal替換List集合中所有的舊值oldVal

checkedxxx 檢查集合

返回類型檢查的集合,在對類型進行set 或者add的時候會做類型檢查

用法:

ArrayList list = Lists.newArrayList(); list.add(new Player("香菜")); // 返回的safeList 在add時會進行類型檢查 List safeList = Collections.checkedList(list, Player.class); //此時會對類型進行檢查,不是Player類型,拋出異常 java.lang.ClassCastException: safeList.add("xxx");

源碼解析:

public void add(E e) { i.add(typeCheck(e)); } E typeCheck(Object o) { if (o != null && !type.isInstance(o)) throw new ClassCastException(badElementMsg(o)); return (E) o; }

這一組的函數可以在開發中多用,儘量避免因為不小心或者因為多人合作的原因出現一些異常。

emptyxxx 返回空的集合

這個操作有點騷,就是直接返回一個空集合,不能添加,不能刪除,這個東西會有什麼用吶?

用法:

/** * 查詢 和我同公會的好友 */ public List<Player> getSameUnionFriend(int roleId,int uid){ // 如果當前玩家沒有工會,直接返回空list if (uid == 0){ return Collections.emptyList(); } // todo .... }

這樣用的好處就是1.不用處理返回null的問題。2.不用新生成空的list,避免佔用內存,因為返回的空list,整個應用共同用一個。你發現他的好處了嗎?

源碼解析:

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

synchronizedxxx 同步集合

用法:

ArrayList<Player> list = Lists.newArrayList(); // TODO; List<Player> synList = Collections.synchronizedList(list);

將傳入的集合進行同步。解決線程同步問題。

源碼:

final Object mutex; // Object on which to synchronizepublic void add(int index, E element) {synchronized (mutex) {list.add(index, element);} }

這種方式相當於對集合進行了二次包裝,在內部加了一把鎖。

注意:這樣的加鎖方式會產生問題,如果是集合的單個操作是沒有問題的,如果想同步集合狀態下做一些非元操作是有問題的。還是要使用synchronize(list),小心使得萬年船。

unmodifiableXxx 不可變集合

用法:傳入的集合返回後不可以改變。

ArrayList<Player> list = Lists.newArrayList();// TODO; List<Player> synList = Collections.unmodifiableList(list);

源碼:

public E set(int index, E element) {throw new UnsupportedOperationException(); } public void add(int index, E element) { throw new UnsupportedOperationException(); } public E remove(int index) { throw new UnsupportedOperationException(); }

傳入的集合不可以改變。因為包裝類屏蔽了集合的方法,拋出了異常。

注意:只是不可以修改list的內容,但是可以修改list內元素的內容。比如下面:

ArrayList<Player> list = Lists.newArrayList();list.add(new Player("香菜聊遊戲")); List<Player> synList = Collections.unmodifiableList(list); Player player = synList.get(0); player.setName("蘿蔔");

總結

Collections 支持單個元素的除集合外提供的泛型操作。

如果你想同步集合,請用synchronizedxxx 。

如果你不想修改集合,請用unmodifiableXxx 。

如果你想使用空集合,請用emptyXxx。

如果你想保持集合純淨,請用 checkedxxx 。

相關焦點

  • 會寫Java,不一定會用Collections,你會用嗎
    這是系列的第四篇,不容易,總算還在軌道上。今天寫一下 Collections,這是Java官方提供的針對集合類的工具類,也是在開發中的一把利刃,能幫我們解決很多開發中的問題,但是依然有很多人不會或者不了解其中的API,一起學習下。
  • 細思極恐,你真的會寫java嗎
    原文地址:http://lrwinx.github.io/2017/03/04/細思極恐-你真的會寫java嗎/作者: Lrwin導語自2013年畢業後,今年已經是我工作的第4個年頭了,總在做java相關的工作,終於有時間坐下來,寫一篇關於java寫法的一篇文章,來探討一下如果你真的是一個java程式設計師,那你真的會寫java嗎?
  • 細思極恐 —— 你真的會寫 Java 嗎?
    相關的工作,終於有時間坐下來,寫一篇關於java寫法的一篇文章,來探討一下如果你真的是一個java程式設計師,那你真的會寫java嗎?別告訴我快捷鍵不好用更換IDE不在我本文的重點內容中,所以不下想用太多的篇幅去寫為什麼更換IDE,請谷歌。在這裡,我只能告訴你,更換IDE只為了更好、更快的寫好java代碼。原因略。別告訴我快捷鍵不好用,請嘗試新事物。beanbean使我們使用最多的模型之一,我將以大篇幅去講解bean,希望讀者好好體會。
  • 細思極恐-你真的會寫java嗎?
    來探討一下如果你真的是一個java程式設計師,那你真的會寫java嗎?思考與重構我相信這個需求看似很簡單,無論怎麼寫都可以完成。很多人可能看到這個需求,就動手開始寫Calendar或Date進行計算,從而完成需求。而我給的建議是,仔細考慮如何寫代碼,然後再去寫,不是說所有的時間操作都用Calendar或Date去解決,一定要看場景。
  • 細思極恐-你真的會寫Java嗎?
    連結:http://lrwinx.github.io/2017/03/04/細思極恐-你真的會寫java嗎/ 自2013年畢業後,今年已經是我工作的第4個年頭了,總在做Java相關的工作,終於有時間坐下來,寫一篇關於Java寫法的一篇文章,來探討一下如果你真的是一個Java程式設計師,那你真的會寫Java嗎?
  • 細思極恐 - 你真的會寫 Java 嗎?
    4個年頭了,總在做java相關的工作,終於有時間坐下來,寫一篇關於java寫法的一篇文章,來探討一下如果你真的是一個java程式設計師,那你真的會寫java嗎?如果你還不理解我說的話,請看一下 Vaughn Vernon 出的一本叫做《IMPLEMENTING DOMAIN-DRIVEN DESIGN》(實現領域驅動設計)這本書,書中講解了貧血模型與領域模型的區別,相信你會受益匪淺。
  • Java中線程池,你真的會用嗎?
    在文中有這樣一段描述:可以通過Executors靜態工廠構建線程池,但一般不建議這樣使用。關於這個問題,在那篇文章中並沒有深入的展開。作者之所以這麼說,是因為這種創建線程池的方式有很大的隱患,稍有不慎就有可能導致線上故障。本文我們就來圍繞這個問題來分析一下為什麼JDK自身提供的構建線程池的方式並不建議使用?
  • 我用 Java 8 寫了一段邏輯,同事直呼看不懂,你試試看..
    }  } }}獲取一個物流信息這麼麻煩,我也是醉了,這樣寫也太不優雅了。實現原理其實這並沒有用什麼高超的技術,就是利用 Java 8 Optional 來實現的,細節就不介紹了 ,主要是為了避免空指針而生的,不懂的可以點擊這裡查看這篇文章。
  • java程序編譯後會產生什麼
    Java類的編譯與反編譯   我們在最初學習Java的時候,會接觸到兩個命令:javac和java,那個時候我們就知道,javac是用來編譯Java類的,就是將我們寫好的helloworld.java文件編譯成helloworld.class文件。
  • Java中的BigDecimal,你真的會用嗎?
    一般情況下,對於那些不需要準確計算精度的數字,我們可以直接使用Float和Double處理,但是Double.valueOf(String) 和Float.valueOf(String)會丟失精度。所以開發中,如果我們需要精確計算的結果,則必須使用BigDecimal類來操作。
  • Java 中的 BigDecimal,你真的會用嗎?
    一般情況下,對於那些不需要準確計算精度的數字,我們可以直接使用Float和Double處理,但是Double.valueOf(String) 和Float.valueOf(String)會丟失精度。所以開發中,如果我們需要精確計算的結果,則必須使用BigDecimal類來操作。
  • Python的collections原來這麼好用!
    Counter是一個dict子類,主要是用來對你訪問的對象的頻率進行計數。返回一個新的雙向隊列對象,從左到右初始化(用方法 append()),從 iterable(迭代對象)數據創建。'g', 'f', 'p', 'y', 't', 'h', 'o', 'n'], maxlen=10)>>> d.append('m')>>> ddeque(['h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n', 'm'], maxlen=10)問題背景是我們有多個字典或者映射,想把它們合併成為一個單獨的映射,有人說可以用
  • java工程師工資一般多少?java自學容易嗎?公司會要嗎-開課吧
    零基礎學Java容易的前提是,你要知道從哪裡開始學起,學到什麼程度可以開始自己做一些小的項目,或者自己寫一個商城類的項目。學任何東西,初入門都會有一定難度,其實這沒什麼,每個人都遇到這道坎的。我的經驗,學任何東西,難並不可怕,難的是畏懼。
  • 用記事本寫一個Java程序
    在D盤根目錄下新建一個test文件夾,並在該文件夾中新建文本文檔,重命名為HelloWorld.java後,用記事本方式打開,在其中編寫一段Java代碼
  • 學java編程一定要會英語嗎?關於這個我給你說句實話
    最近收到很多同學的這樣一個問題,就是說學習Java編程一定需要很好的英語嗎?是不是英語不好就不能學習Java了?我相信一直有很多小夥伴被這個問提所困擾,因為我們可能都知道,學習編程都是用英文在寫相關代碼。那麼我的英語恰好學得不是那麼的好,甚至很差,那我到底能不能學習編程呢?
  • Lambda表達式你會用嗎?
    (至於Lambda表達式的語法,我們下面章節再詳細介紹)如果你的邏輯不止一行代碼,那麼你還可以這麼寫Thread thread = new Thread(() -> {    System.out.println("Thread Run");    System.out.println("Hello")
  • 面試被問Excel會用嗎?PPT會做嗎?你說會一點,為什麼會被pass
    存在的差別就是每個崗位的側重點會不一樣,word是每個崗位都會需要掌握的,至少平時寫個工作總結、工作報告、方案等是沒有問題的。差別比較大的是Excel和PPT,有些崗位會要求Excel比較精通,各種函數、公式、數據分析都能熟練操作;而有些崗位可能會要求PPT水平比較高,能製作得比較精美。
  • 你這輩子一定會用上的軟體!
    軟體下載連結在最下面    不管你是在工作還是在學習,我接下來說的這些軟體,我相信你這輩子一定會用上
  • 「你會說漢語嗎?」用英語怎麼說?
    提到「你會說漢語/中文嗎?」,很多人可能會馬上想到兩種表達1)Do you speak Chinese?2) Can you speak Chinese?兩個表達沒有太大問題。然而在實際運用中,容易產生理解歧義。
  • Java的「泛型」特性,你以為自己會了?(萬字長文)
    ,例如集合、反射、泛型、註解等等,這些可以說我們在平時開發中是經常使用到的,尤其是集合,基本是只要寫代碼沒有用不到的,今天我們先來談談泛型。- (表示不確定的java類型)但是泛型的參數只能是類類型,不能是基本的數據類型,他的類型一定是自Object的注意:泛型不接受基本數據類型,換句話說,只有引用類型才能作為泛型方法的實際參數2. 為什麼要使用泛型?