Java容器部分上(重要)

1.java容器都有哪些?(容器指的是集合類)

基本概念

Java容器類類庫的用途是“持有對象”涂炎,并將其劃分為兩個不同的概念:

1)Collection:一個獨(dú)立元素的序列纲菌,這些元素都服從一條或者多條規(guī)則钱慢。?List必須按照插入的順序保存元素,而set不能有重復(fù)的元素缘眶。Queue按照排隊規(guī)則來確定對象產(chǎn)生的順序(通常與它們被插入的順序相同)腻窒。?

2)Map:一組成對的“鍵值對”對象,允許你使用鍵來查找值磅崭。

|Collection?

|  ├List?

|  │-├LinkedList?

|  │-├ArrayList?

|  │-└Vector?

|  │ └Stack?

|  ├Set?

|  │├HashSet?

|  │├TreeSet?

|  │└LinkedSet?

|?

|Map?

  ├Hashtable?

  ├HashMap?

  └WeakHashMap


2.Collection 和 Collections 有什么區(qū)別儿子?

注:?1、java.util.Collection 是一個集合接口砸喻。它提供了對集合對象進(jìn)行基本操作的通用接口方法柔逼。Collection接口在Java 類庫中有很多具體的實現(xiàn)蒋譬。Collection接口的意義是為各種具體的集合提供了最大化的統(tǒng)一操作方式。?

  2愉适、java.util.Collections 是一個包裝類犯助。它包含有各種有關(guān)集合操作的靜態(tài)多態(tài)方法。此類不能實例化维咸,就像一個工具類剂买,服務(wù)于Java的Collection框架。


3.List癌蓖、Set瞬哼、Map 之間的區(qū)別是什么?

答:

1.List:

可以允許重復(fù)對象租副、可以插入多個null元素坐慰、是一個有序容器

2.Set:

不允許重復(fù)對象、只允許一個null元素用僧、無序容器

3.Map:

?Map不是Collection的子接口或?qū)崿F(xiàn)類结胀。Map是一個接口、Map 的每個Entry都特有兩個對象责循,也就是一個鍵一個值糟港,Map可能會持有相同的值對象但鍵對象必須是唯一的、Map里可以擁有隨意個niull值但最多只能有一個null鍵


4.HashMap 和 Hashtable 有什么區(qū)別院仿?

?1.Map是一個以鍵值對存儲的接口着逐。Map下有兩個具體的實現(xiàn),分別是HashMap和HashTable.

2.HashMap是線程非安全的意蛀,HashTable是線程安全的,所以HashMap的效率高于HashTable.

3.HashMap允許鍵或值為空健芭,而HashTable不允許鍵或值為空.

4.繼承關(guān)系不同:

???HashTable?

????????????public class Hashtable<K,V> extends Dictionary<K,V>1.0

????????????implements Map<K,V>, Cloneable, java.io.Serializable {}

???HashMap

????????????public class HashMap<K,V>?extends AbstractMap<K,V>1.2

????????????implements Map<K,V>, Cloneable, Serializable{}


5.HashMap性能為什么優(yōu)于Hashtable县钥?

?????HashTable容器使用synchronized來保證線程安全,但在線程競爭激烈的情況下HashTable的效率非常低下慈迈。因為當(dāng)一個線程訪問HashTable的同步方法時若贮,其他線程訪問HashTable的同步方法時,可能會進(jìn)入阻塞或輪詢狀態(tài)痒留。如線程1使用put進(jìn)行添加元素谴麦,線程2不但不能使用put方法添加元素,并且也不能使用get方法來獲取元素伸头,所以競爭越激烈效率越低匾效。

附加問題:

我們可以使用CocurrentHashMap來代替Hashtable嗎?

我們知道Hashtable是synchronized的恤磷,但是ConcurrentHashMap同步性能更好面哼,因為它僅僅根據(jù)同步級別對map的一部分進(jìn)行上鎖野宜。ConcurrentHashMap當(dāng)然可以代替HashTable,但是HashTable提供更強(qiáng)的線程安全性魔策。它們都可以用于多線程的環(huán)境匈子,但是當(dāng)Hashtable的大小增加到一定的時候,性能會急劇下降闯袒,因為迭代時需要被鎖定很長的時間虎敦。因為ConcurrentHashMap引入了分割(segmentation),不論它變得多么大政敢,僅僅需要鎖定map的某個部分其徙,而其它的線程不需要等到迭代完成才能訪問map。簡而言之堕仔,在迭代的過程中擂橘,ConcurrentHashMap僅僅鎖定map的某個部分,而Hashtable則會鎖定整個map摩骨。CocurrentHashMap在JAVA8中存在一個bug通贞,會進(jìn)入死循環(huán),原因是遞歸創(chuàng)建ConcurrentHashMap 對象


6.如何決定使用HashMap還是 TreeMap恼五?


7.說一下 HashMap 的實現(xiàn)原理昌罩?

如圖所示,HashMap底層是基于數(shù)組和鏈表實現(xiàn)的灾馒。其中有兩個重要的參數(shù):

容量茎用、負(fù)載因子

容量的默認(rèn)大小是16,負(fù)載因子是 0.75睬罗,當(dāng)?HashMap?的?size > 16*0.75時就會發(fā)生擴(kuò)容(容量和負(fù)載因子都可以自由調(diào)整)轨功。

Put方法:

首先會將傳入的Key做?hash運(yùn)算計算出 hashcode,然后根據(jù)數(shù)組長度取模計算出在數(shù)組中的 index 下標(biāo)。

由于在計算中位運(yùn)算比取模運(yùn)算效率高的多容达,所以HashMap規(guī)定數(shù)組的長度為?2^n古涧。這樣用?2^n - 1做位運(yùn)算與取模效果一致,并且效率還要高出許多花盐。

由于數(shù)組的長度有限羡滑,所以難免會出現(xiàn)不同的Key通過運(yùn)算得到的 index 相同,這種情況可以利用鏈表來解決算芯,HashMap 會在?table[index]處形成鏈表柒昏,采用頭插法將數(shù)據(jù)插入到鏈表中。

get方法:

get和 put 類似熙揍,也是將傳入的 Key 計算出 index 职祷,如果該位置上是一個鏈表就需要遍歷整個鏈表,通過?key.equals(k)來找到對應(yīng)的元素。

遍歷方式:

?Iterator<Map.Entry<String, Integer>> entryIterator = map.entrySet().iterator();

????????while (entryIterator.hasNext()) {

????????????Map.Entry<String, Integer> next = entryIterator.next();

????????????System.out.println("key=" + next.getKey() + " value=" + next.getValue());

????????}

Iterator<String> iterator = map.keySet().iterator();

????????while (iterator.hasNext()){

????????????String key = iterator.next();

????????????System.out.println("key=" + key + " value=" + map.get(key));

????????}

map.forEach((key,value)->{

????System.out.println("key=" + key + " value=" + value);});

強(qiáng)烈建議使用第一種EntrySet進(jìn)行遍歷堪旧。

第一種可以把key value同時取出削葱,第二種還得需要通過 key 取一次 value,效率較低, 第三種需要?JDK1.8以上淳梦,通過外層遍歷 table析砸,內(nèi)層遍歷鏈表或紅黑樹。

死循環(huán)問題:

在并發(fā)環(huán)境下使用HashMap容易出現(xiàn)死循環(huán)爆袍。

并發(fā)場景發(fā)生擴(kuò)容首繁,調(diào)用resize()方法里的?rehash()時,容易出現(xiàn)環(huán)形鏈表陨囊。這樣當(dāng)獲取一個不存在的?key時弦疮,計算出的index正好是環(huán)形鏈表的下標(biāo)時就會出現(xiàn)死循環(huán)。

所以HashMap只能在單線程中使用蜘醋,并且盡量的預(yù)設(shè)容量胁塞,盡可能的減少擴(kuò)容。

在JDK1.8中對?HashMap進(jìn)行了優(yōu)化: 當(dāng)?hash碰撞之后寫入鏈表的長度超過了閾值(默認(rèn)為8)并且?table的長度不小于64(否則擴(kuò)容一次)時压语,鏈表將會轉(zhuǎn)換為紅黑樹啸罢。

假設(shè)hash沖突非常嚴(yán)重,一個數(shù)組后面接了很長的鏈表胎食,此時重新的時間復(fù)雜度就是?O(n)扰才。

如果是紅黑樹,時間復(fù)雜度就是O(logn)厕怜。

大大提高了查詢效率衩匣。

多線程場景下推薦使用CocurrentHashMap。


8.說一下 HashSet 的實現(xiàn)原理粥航?

HashSet是一個不允許存儲重復(fù)元素的集合琅捏,它的實現(xiàn)比較簡單,只要理解了?HashMap递雀,HashSet就水到渠成了柄延。

成員變量:

首先了解下HashSet的成員變量:

????private transient HashMap<E,Object> map;

????// Dummy value to associate with an Object in the backing Map

????private static final Object PRESENT = new Object();

發(fā)現(xiàn)主要就兩個變量:

map:用于存放最終數(shù)據(jù)的。

PRESENT:是所有寫入 map 的?value值映之。

構(gòu)造函數(shù):

????public HashSet() {

????????map = new HashMap<>();

????}

????public HashSet(int initialCapacity, float loadFactor) {

????????map = new HashMap<>(initialCapacity, loadFactor);

????} ???

構(gòu)造函數(shù)很簡單,利用了HashMap初始化了?map蜡坊。

add:

????public boolean add(E e) {

????????return map.put(e, PRESENT)==null;

????}

比較關(guān)鍵的就是這個add()方法杠输。 可以看出它是將存放的對象當(dāng)做了?HashMap的健,value都是相同的?PRESENT秕衙。由于?HashMap的?key是不能重復(fù)的蠢甲,所以每當(dāng)有重復(fù)的值寫入到?HashSet時,value會被覆蓋据忘,但?key不會受到影響鹦牛,這樣就保證了?HashSet中只能存放不重復(fù)的元素搞糕。

總結(jié):

HashSet的原理比較簡單,幾乎全部借助于?HashMap來實現(xiàn)的曼追。

所以HashMap會出現(xiàn)的問題?HashSet依然不能避免窍仰。


9.ArrayList 和 LinkedList 的區(qū)別是什么?

Arraylist:底層是基于動態(tài)數(shù)組礼殊,根據(jù)下表隨機(jī)訪問數(shù)組元素的效率高驹吮,向數(shù)組尾部添加元素的效率高;但是晶伦,刪除數(shù)組中的數(shù)據(jù)以及向數(shù)組中間添加數(shù)據(jù)效率低碟狞,因為需要移動數(shù)組。例如最壞的情況是刪除第一個數(shù)組元素婚陪,則需要將第2至第n個數(shù)組元素各向前移動一位族沃。而之所以稱為動態(tài)數(shù)組,是因為Arraylist在數(shù)組元素超過其容量大泌参,Arraylist可以進(jìn)行擴(kuò)容(針對JDK1.8? 數(shù)組擴(kuò)容后的容量是擴(kuò)容前的1.5倍)脆淹,Arraylist源碼中最大的數(shù)組容量是Integer.MAX_VALUE-8,對于空出的8位及舍,目前解釋是 :①存儲Headerwords未辆;②避免一些機(jī)器內(nèi)存溢出,減少出錯幾率锯玛,所以少分配③最大還是能支持到Integer.MAX_VALUE(當(dāng)Integer.MAX_VALUE-8依舊無法滿足需求時).只要ArrayList的當(dāng)前容足夠大咐柜,add()操作向數(shù)組的尾部的效率非常高的,當(dāng)向數(shù)組指定位置添加yi據(jù)時攘残,會進(jìn)行大量的數(shù)組移動復(fù)制操作拙友。而數(shù)組復(fù)制時,最終將調(diào)用System.arraycopy()方法歼郭,因此add()操作的效率還是相當(dāng)高的遗契。盡管這樣當(dāng)向指定位置添加數(shù)據(jù)時也還是比Linkedlist慢,后者添加數(shù)據(jù)只需要改變指針指向即可病曾。Arraylist刪除數(shù)組也需要移動數(shù)組牍蜂,效率較慢。

Linkedlist基于鏈表的動態(tài)數(shù)組泰涂,數(shù)據(jù)添加刪除效率高鲫竞,只需要改變指針指向即可,但是訪問數(shù)據(jù)的平均效率低逼蒙,需要對鏈表進(jìn)行遍歷从绘。

總結(jié):

1、對于隨機(jī)訪問get和set,ArrayList覺得優(yōu)于LinkedList僵井,因為LinkedList要移動指針陕截。?對于新增和刪除操作add和remove,LinedList比較占優(yōu)勢批什,因為ArrayList要移動數(shù)據(jù)农曲。

2、各自效率問題:


10.如何實現(xiàn)數(shù)組和List之間的轉(zhuǎn)換渊季?

List轉(zhuǎn)數(shù)組:

toArray(arraylist.size()方法

數(shù)組轉(zhuǎn)List:

1.Arrays的asList(a)方法(效率不高)

2.通過集合工具類Collections.addAll()方法(最高效)通過Collections.addAll(arrayList, strArray)方式轉(zhuǎn)換朋蔫,根據(jù)數(shù)組的長度創(chuàng)建一個長度相同的List,然后通過Collections.addAll()方法却汉,將數(shù)組中的元素轉(zhuǎn)為二進(jìn)制驯妄,然后添加到List中,這是最高效的方法合砂。


11.ArrayList 和 Vector 的區(qū)別是什么哼拔?

ArrayList實現(xiàn)于?List渊跋、RandomAccess?接口险领∶际可以插入空數(shù)據(jù),也支持隨機(jī)訪問缘屹。

ArrayList相當(dāng)于動態(tài)數(shù)據(jù)凛剥,其中最重要的兩個屬性分別是:?elementData?數(shù)組,以及?size?大小轻姿。 在調(diào)用?add()?方法的時候:

????public boolean add(E e) {

????????ensureCapacityInternal(size + 1); ?// Increments modCount!!

????????elementData[size++] = e;

????????return true;

????}

首先進(jìn)行擴(kuò)容校驗犁珠。

將插入的值放到尾部,并將size + 1互亮。

如果是調(diào)用add(index,e)在指定位置添加的話:

????public void add(int index, E element) {

????????rangeCheckForAdd(index);

????????ensureCapacityInternal(size + 1); ?// Increments modCount!!

? ? ? ? //復(fù)制犁享,向后移動

????????System.arraycopy(elementData, index, elementData, index + 1,

?????????????????????????size - index);

????????elementData[index] = element;

????????size++;

????}

也是首先擴(kuò)容校驗。

接著對數(shù)據(jù)進(jìn)行復(fù)制豹休,目的是把index位置空出來放本次插入的數(shù)據(jù)炊昆,并將后面的數(shù)據(jù)向后移動一個位置。

其實擴(kuò)容最終調(diào)用的代碼:

????private void grow(int minCapacity) {

????????// overflow-conscious code

????????int oldCapacity = elementData.length;

????????int newCapacity = oldCapacity + (oldCapacity >> 1);

????????if (newCapacity - minCapacity < 0)

????????????newCapacity = minCapacity;

????????if (newCapacity - MAX_ARRAY_SIZE > 0)

????????????newCapacity = hugeCapacity(minCapacity);

????????// minCapacity is usually close to size, so this is a win:

????????elementData = Arrays.copyOf(elementData, newCapacity);

????}

也是一個數(shù)組復(fù)制的過程威根。

由此可見ArrayList的主要消耗是數(shù)組擴(kuò)容以及在指定位置添加數(shù)據(jù)凤巨,在日常使用時最好是指定大小,盡量減少擴(kuò)容洛搀。更要減少在指定位置插入數(shù)據(jù)的操作敢茁。

序列化:

由于ArrayList是基于動態(tài)數(shù)組實現(xiàn)的,所以并不是所有的空間都被使用姥卢。因此使用了?transient?修飾卷要,可以防止被自動序列化。

transient Object[] elementData;

因此ArrayList自定義了序列化與反序列化:

????private void writeObject(java.io.ObjectOutputStream s)

????????throws java.io.IOException{

????????// Write out element count, and any hidden stuff

????????int expectedModCount = modCount;

????????s.defaultWriteObject();

????????// Write out size as capacity for behavioural compatibility with clone()

????????s.writeInt(size);

????????// Write out all elements in the proper order.

//只序列化了被使用的數(shù)據(jù)

????????for (int i=0; i<size; i++) {

????????????s.writeObject(elementData[i]);

????????}

????????if (modCount != expectedModCount) {

????????????throw new ConcurrentModificationException();

????????}

????}

????private void readObject(java.io.ObjectInputStream s)

????????throws java.io.IOException, ClassNotFoundException {

????????elementData = EMPTY_ELEMENTDATA;

????????// Read in size, and any hidden stuff

????????s.defaultReadObject();

????????// Read in capacity

????????s.readInt(); // ignored

????????if (size > 0) {

????????????// be like clone(), allocate array based upon size not capacity

????????????ensureCapacityInternal(size);

????????????Object[] a = elementData;

????????????// Read in all elements in the proper order.

????????????for (int i=0; i<size; i++) {

????????????????a[i] = s.readObject();

????????????}

????????}

????}

當(dāng)對象中自定義了writeObject和 readObject 方法時独榴,JVM 會調(diào)用這兩個自定義方法來實現(xiàn)序列化與反序列化僧叉。

從實現(xiàn)中可以看出ArrayList只序列化了被使用的數(shù)據(jù)。

Vector:

Vector也是實現(xiàn)于?List?接口棺榔,底層數(shù)據(jù)結(jié)構(gòu)和?ArrayList?類似,也是一個動態(tài)數(shù)組存放數(shù)據(jù)瓶堕。不過是在?add()?方法的時候使用?synchronized?進(jìn)行同步寫數(shù)據(jù),但是開銷較大症歇,所以?Vector?是一個同步容器并不是一個并發(fā)容器郎笆。

以下是add()方法:

????public synchronized boolean add(E e) {

????????modCount++;

????????ensureCapacityHelper(elementCount + 1);

????????elementData[elementCount++] = e;

????????return true;

????}

以及指定位置插入數(shù)據(jù):

????public void add(int index, E element) {

????????insertElementAt(element, index);

????}

????public synchronized void insertElementAt(E obj, int index) {

????????modCount++;

????????if (index > elementCount) {

????????????throw new ArrayIndexOutOfBoundsException(index

?????????????????????????????????????????????????????+ " > " + elementCount);

????????}

????????ensureCapacityHelper(elementCount + 1);

????????System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);

????????elementData[index] = obj;

????????elementCount++;

????}


12.Array 和 ArrayList 有何區(qū)別?

Array可以包含基本類型和對象類型忘晤,ArrayList只能包含對象類型

  Array大小固定宛蚓,ArrayList的大小是動態(tài)變化的。

  ArrayList提供了更多的方法和特性:比如 :addAll(),removeAll(),iterator()等等设塔。

  對于基本數(shù)據(jù)類型凄吏,集合使用自動裝箱來減少編碼工作量。但是闰蛔,當(dāng)處理固定大小基本數(shù)據(jù)類型的時候痕钢,這種方式相對較慢。


13.在Queue中poll()和remove()有什么區(qū)別序六?

poll()和 remove() 都是從隊列中取出一個元素任连,但是 poll() 在獲取元素失敗的時候會返回空,但是 remove() 失敗的時候會拋出異常例诀。


14.哪些集合類是線程安全的随抠?

Vector:就比ArrayList多了一個同步化機(jī)制(線程安全)

LinkedList因為成員方法大多是synchronized的,因此LinkedList是線程安全的余佃。而ArrayList不是線程安全的暮刃。在擴(kuò)容機(jī)制上,當(dāng)Vector的元素數(shù)量超過它的初始化大小的時候會將容量翻倍爆土,而ArrayList只會增長50%椭懊。

ArrayList的數(shù)據(jù)結(jié)構(gòu)是基于數(shù)組的(Object[]),而LinkList內(nèi)部結(jié)構(gòu)是基于一組鏈接的記錄,形式上屬于鏈表的步势。所以在增加元素方面linkList的效率更高氧猬,因為在ArrayList中增加元素,會牽扯一次重新排序坏瘩。刪除也是類似盅抚,所以ArrayList的查詢性能要好些。反之LinkList增加倔矾,刪除性能更好妄均。如果是迭代讀取的話柱锹,就沒有什么差別了。

HashTable:比hashMap多了一個線程安全丰包。hashTable的方法都提供了同步機(jī)制禁熏。hashTable不允許插入空值,hashMap是允許的邑彪。

ConcurrentHashMap:是一種高效但是也線程安全的集合瞧毙。它比Hashmap來講,是線程安全的寄症,但是效率也比較高宙彪,因為它引入了一個分段鎖的概念,可以理解為把一個大的Map拆分成了N個小的hashTable有巧。根據(jù)key.hashCode()決定把key放到哪個hashtable中释漆。HashMap的數(shù)據(jù)結(jié)構(gòu)是數(shù)據(jù)和鏈表。通過hash算法計算該key所在的數(shù)組下標(biāo)篮迎,根據(jù)equals取比較值灵汪。通俗的說救贖ConcurrenthashMap是對每個數(shù)組進(jìn)行加鎖,當(dāng)通過hash算法得出的結(jié)果相同時才需要去同步數(shù)據(jù)柑潦。


15.迭代器Iterator 是什么享言?

對Collection 進(jìn)行迭代的類,稱其為迭代器渗鬼。還是面向?qū)ο蟮乃枷肜缆叮瑢I(yè)對象做專業(yè)的事情,迭代器就是專門取出集合元素的對象譬胎。但是該對象比較特殊差牛,不能直接創(chuàng)建對象(通過new),該對象是以內(nèi)部類的形式存在于每個集合類的內(nèi)部堰乔。


16.Iterator 怎么使用偏化?有什么特點(diǎn)?

Collection接口中定義了獲取集合類迭代器的方法(iterator())镐侯,所以所有的Collection體系集合都可以獲取自身的迭代器侦讨。


17.Iterator 和 ListIterator 有什么區(qū)別?

1. ListIterator有add()方法苟翻,可以向List中添加對象韵卤,而Iterator不能

2. ListIterator和Iterator都有hasNext()和next()方法,可以實現(xiàn)順序向后遍歷崇猫,但是ListIterator有hasPrevious()和previous()方法沈条,可以實現(xiàn)逆向(順序向前)遍歷。Iterator就不可以诅炉。

3. ListIterator可以定位當(dāng)前的索引位置蜡歹,nextIndex()和previousIndex()可以實現(xiàn)屋厘。Iterator沒有此功能。

4. 都可實現(xiàn)刪除對象月而,但是ListIterator可以實現(xiàn)對象的修改擅这,set()方法可以實現(xiàn)。Iierator僅能遍歷景鼠,不能修改。


18.怎么確保一個集合不能被修改痹扇?

Collections.unmodifiableList(List)

Collections.unmodifiableMap(Map)

Collections.unmodifiableSet(Set)

可以返回一個只讀視圖不能修改


19.List铛漓、Map、Set三個接口鲫构,存取元素時浓恶,各有什么特點(diǎn)?

List?以特定次序來持有元素结笨,可有重復(fù)元素包晰。即,有序可重復(fù)炕吸。

訪問時可以使用for循環(huán)伐憾,foreach循環(huán),iterator迭代器 迭代赫模。

Set?無法擁有重復(fù)元素,內(nèi)部排序树肃。即,無序不可重復(fù)瀑罗。

訪問時可以使用foreach循環(huán)胸嘴,iterator迭代器 迭代。

Map?保存?key-value?值斩祭,一一映射劣像。key值 是無序,不重復(fù)的摧玫。value值可重復(fù)耳奕。

訪問時可以map中key值轉(zhuǎn)為為set存儲,然后迭代這個set诬像,用map.get(key)獲取value


20.對比Hashtable吮铭、HashMap、TreeMap有什么不同颅停?

HashTable HashMap TreeMap都是最常見的一些Map實現(xiàn),是以鍵值對的形式存儲和操作數(shù)據(jù)的容器類型谓晌。

HashTable是早期Java類庫提供的一個哈希表實現(xiàn),本身是同步的,不支持null鍵和值,由于同步導(dǎo)致的性能開銷,所以已經(jīng)很少被推薦使用。

HashMap是應(yīng)用更加廣泛的哈希表實現(xiàn),行為大致上與HashTable一致,主要區(qū)別在于HashMap不是同步的,支持null鍵和值等癞揉。通常情況下,HashMap進(jìn)行put或者get操作,可以達(dá)到常數(shù)時間的性能,所以它是絕大部分利用鍵值對存儲場景的首選,比如,實現(xiàn)一個用戶ID和用戶信息對應(yīng)的運(yùn)行時存儲結(jié)構(gòu)纸肉。

TreeMap則是基于紅黑樹的一種提供順序訪問的Map,和HashMap不同,它的get remove之類操作都是O(long(n)的時間復(fù)雜度,具體順序可以由指定的Comparator來決定或者根據(jù)鍵的自然順序來判斷溺欧。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市柏肪,隨后出現(xiàn)的幾起案子姐刁,更是在濱河造成了極大的恐慌,老刑警劉巖烦味,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聂使,死亡現(xiàn)場離奇詭異,居然都是意外死亡谬俄,警方通過查閱死者的電腦和手機(jī)柏靶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溃论,“玉大人屎蜓,你說我怎么就攤上這事≡垦” “怎么了炬转?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長算灸。 經(jīng)常有香客問我扼劈,道長,這世上最難降的妖魔是什么菲驴? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任测僵,我火速辦了婚禮,結(jié)果婚禮上谢翎,老公的妹妹穿的比我還像新娘捍靠。我一直安慰自己,他們只是感情好森逮,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布榨婆。 她就那樣靜靜地躺著,像睡著了一般褒侧。 火紅的嫁衣襯著肌膚如雪良风。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天闷供,我揣著相機(jī)與錄音烟央,去河邊找鬼。 笑死歪脏,一個胖子當(dāng)著我的面吹牛疑俭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播婿失,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼钞艇,長吁一口氣:“原來是場噩夢啊……” “哼啄寡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起哩照,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤挺物,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后飘弧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體识藤,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年次伶,在試婚紗的時候發(fā)現(xiàn)自己被綠了痴昧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡学少,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秧骑,到底是詐尸還是另有隱情版确,我是刑警寧澤,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布乎折,位于F島的核電站绒疗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骂澄。R本人自食惡果不足惜吓蘑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坟冲。 院中可真熱鬧磨镶,春花似錦、人聲如沸健提。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽私痹。三九已至脐嫂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間紊遵,已是汗流浹背账千。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留暗膜,地道東北人匀奏。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像学搜,于是被迫代替她去往敵國和親攒射。 傳聞我的和親對象是個殘疾皇子醋旦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Java集合詳解 [if !supportLists]一、[endif]集合的由來 通常会放,我們的程序需要根據(jù)程序運(yùn)...
    秋刀魚茶泡飯QAQ閱讀 466評論 1 2
  • ArrayList 詳解 底層是數(shù)組饲齐,查詢快增刪慢,線程不安全咧最,效率高捂人。初始化長度10 說一下ArrayList底...
    奇點(diǎn)一氪閱讀 400評論 0 0
  • title: java集合框架學(xué)習(xí)總結(jié) tags:集合框架 categories:總結(jié) date: 2017-03...
    行徑行閱讀 1,690評論 0 2
  • 集合 集合與數(shù)組 數(shù)組(可以存儲基本數(shù)據(jù)類型)是用來存現(xiàn)對象的一種容器,但是數(shù)組的長度固定矢沿,不適合在對象數(shù)量未知的...
    手打小黑板閱讀 352評論 0 0
  • 本系列出于AWeiLoveAndroid的分享滥搭,在此感謝,再結(jié)合自身經(jīng)驗查漏補(bǔ)缺捣鲸,完善答案瑟匆。以成系統(tǒng)。 Java基...
    濟(jì)公大將閱讀 1,529評論 1 6