1. 程式人生 > >java基礎—常用的集合類有哪些?比如List如何排序?

java基礎—常用的集合類有哪些?比如List如何排序?

對於集合,大家都不陌生了,常見的集合介面Set、List、Map等,其中Set和List繼承自Collection。


Collection是一組物件的集合,而Map儲存的方式不一樣,他是以鍵值對的形式存放多個物件的。


Set和List又有區別,Set中的元素無序且不重複,而List中的元素則是有序且允許重複的。


Set、List、Map都是介面類,定義的是規範,具體使用時,還是需要其實現類的例項。一般我們見得比較多的就是HashSet、TreeSet、ArrayList、LinkedList、HashMap等,另外還有Vector、HashTable什麼的,這個涉及了多執行緒中的執行緒安全以及效能問題,現在出場率比較低了。


Set:HashSet、TreeSet


說實話,就個人經歷而言,Set的使用比較少,僅在對Map使用Entry的方式進行遍歷的時候,用到過Set的實現類。


關於去重:Set的中判斷放入元素是否重複,都是基於物件的equals()方法的返回值來實現的。


關於順序和排序:其實作為無序的Set,本身應該是不具備排序功能的,因為根本就沒有順序。
HashSet對於元素的儲存位置是取決放入物件的HashCode,是雜湊形式的;另外,還有一個名叫LinkedHashSet的實現類,除了使用HashCode來決定元素位置之外,同時還是用了連結串列來維護元素的次序(Linked),因此對其插入元素時,看起來是有序的;
TreeSet,這個實現類沒有接觸過,以下資料為網路摘抄:


TreeSet是SortedSet介面的唯一實現類,TreeSet可以確保集合元素處於排序狀態。TreeSet支援兩種排序方式,自然排序 和定製排序,其中自然排序為預設的排序方式。
向TreeSet中加入的應該是同一個類的物件。TreeSet判斷兩個物件不相等的方式是兩個物件通過equals方法返回false,或者通過CompareTo方法比較沒有返回0
自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法來比較元素之間大小關係,然後將元素按照升序排列。Java提供了一個Comparable介面,該接口裡定義了一個compareTo(Object obj)方法,該方法返回一個整數值,實現了該介面的物件就可以比較大小。obj1.compareTo(obj2)方法如果返回0,則說明被比較的兩個物件相等,如果返回一個正數,則表明obj1大於obj2,如果是 負數,則表明obj1小於obj2。如果我們將兩個物件的equals方法總是返回true,則這兩個物件的compareTo方法返回應該返回0。
定製排序
自然排序是根據集合元素的大小,以升序排列,如果要定製排序,應該使用Comparator介面,實現 int compare(T o1,T o2)方法。
比較大小的2個介面.jpg
從上面的引文可以看出,對於集合的排序可以使用元素本身比較大小的方法(前提是實現了Comparable介面的物件);或者去實現Comparator介面的compare()方法來自定義一套比較大小的邏輯。


List:ArrayList、LinkedList


這2個應該是很常見的集合實現類了,一個是基於陣列的原理儲存元素,一個是使用連結串列的形式儲存元素,具體的區別不在贅述。
總之,List是有順序的,因此List肯定是可以排序的。考慮到這一點,Java創造者們早就給我們準備好了趁手的工具——Collections,長得有點像Set和List的お父さん(父親),其實根本不是一個世界的人(類);


關於Collections
這是官方提供的一個處理集合的工具方法的集合,本人最熟悉的就是他的sort()方法,對,就是這個排序用的方法,下面我們就來仔細看看這個便利的方法吧。


sort()方法排序的本質其實也是藉助Comparable介面和Comparator介面的實現,一般有2種用法:
1、直接將需要排序的list作為引數傳入,此時list中的物件必須實現了Comparable介面,然後sort會按升序的形式對元素進行排序;
2、傳入list作為第一個引數,同時追加一個Comparator的實現類作為第二個引數,然後sort方法會根據Comparator介面的實現類的邏輯,按升序進行排序;
這裡可能有朋友會問,為什麼都是升序沒有降序。
其實所謂升或者降都是你自己規定的,sort()方法只是將比較結果為-1的放前面,0的放中間,1的放後面;如果你想實現降序排列,那就在Comparator方法的實現類中,逆轉compare的返回結果就行了。


Map:HashMap


看到前面的Set和List的實現類裡面字首都有Array(陣列實現),Hash(雜湊),Linked(連結串列)這幾種儲存方式的實現,我腦洞了一下Map是不是也有ArrayMap呢?


沒有直接百度,而是直接在IDE中去new ArrayMap<K,V>(),發現編譯通不過,看來1.7的JDK是不支援了。


然後開啟度娘模式發現,居然Android裡面有提到,看來我也不算腦洞了。


HashMap算是開發中使用得最多的了,很方法的鍵值對形式(內在是一個一個雜湊分佈的Entry<K,V>,因此可是使用Set<Entry<K,V>>的方式遍歷);


本人對於HashMap基本上遍歷多,排序少,從其字首的Hash可以看出,其鍵值對的存放應該也是根據key的HashCode進行存放;因此,HashMap本身應該是無法排序的,所以跟Set一樣,官方也沒有提供對應的排序方法。


不過,我們可以進行DIY,譬如把HashMap中的key存入可排序的list,進行排序,然後遍歷的時候,通過list或許到key之後,再從Map獲取值這樣就按照key進行排序了。
如果要按照value進行排序就複雜一點,可以把Entry物件放進list,然後自己實現比較器,根據value進行排序。
嗯,還有更多更快更優的方法,大家都可以發散思維。


另外提一嘴,Map中還有TreeMap和LinkedHashMap,其特點就跟Set中的那兩位一樣一樣的。


寫在文尾的體會


不管是Set、List還是Map,根據其不同的特性,有不同的應用場景。


對於排序的問題,根據各種實現類的字首,瞭解實現中的元素儲存方式,可以知道是有序還是無序。由此,可以知道排序是使用官方工具,還是需要自行實現對應的方法。


不論官方還是DIY,總之要繼續排序的基本原理都是藉助Comparable介面和Comparator介面的實現,那麼不論待處理的集合是怎樣的,我們都有辦法應對了。
.