關於Java集合的十大問題
夥伴們注意了!
小編在這裡給大家送上關注福利:
搜尋微訊號“suxueJava”即可領取小編精心準備的資料一份!
以下是在Stackoverflow上詢問和討論的Java集合最流行的問題。
在檢視這些問題之前,最好先檢視類層次圖。
1. 什麼時候使用LinkedList而不是ArrayList?
ArrayList本質上是一個數組。
它的元素可以通過索引直接訪問。
但如果陣列已滿,則需要一個更大的新陣列來分配和移動所有元素到新陣列將花費O(n)時間。
新增或刪除元素還需要移動陣列中的現有元素。
這可能是使用ArrayList的最大缺點。
LinkedList是一個雙鏈表。
因此,要訪問中間的元素,必須從列表的開頭進行搜尋。
另一方面,在LinkedList中新增和刪除元素更快,因為它只在本地更改列表。
綜上所述,時間複雜度比較最壞的情況如下:

儘管執行時間很長,但是對於大型列表來說,記憶體的使用也應該被考慮在內。在LinkedList中,每個節點至少需要兩個額外的指標來連結上一個和下一個節點;而在ArrayList中,只需要一個元素陣列。
2. 在迭代集合時刪除元素的有效等效方法
在迭代時修改集合的惟一正確方法是使用Iterator.remove()。例如,

最常見的錯誤程式碼是

通過執行上面的程式碼,您將獲得一個ConcurrentModificationException異常。
這是因為已經生成了一個迭代器(在for語句中)來遍歷列表,但同時list被iterator .remove()更改。
在Java中,“通常不允許一個執行緒在另一個執行緒遍歷集合時修改該集合”。
3.如何將List轉換為int[]?
最簡單的方法可能是在Apache Commons Lang庫中使用ArrayUtils。

在JDK中,沒有捷徑。
注意,您不能使用List. toarray(),因為這會將List轉換為Integer[]。
正確的方法如下,

4.如何將int[]轉換為List?
最簡單的方法可能仍然是在Apache Commons Lang庫中使用ArrayUtils,如下所示。

在JDK中,也沒有捷徑。

5.篩選集合的最佳方法是什麼?
同樣,您可以使用第三方包,如Guava或Apache Commons Lang來完成此功能。
兩者都提供了filter()方法(在番石榴的Collections2和Apache的CollectionUtils中)。
filter()方法將返回與給定謂詞匹配的元素。
在JDK中,事情變得更加困難。
好訊息是,在Java 8中,將新增謂詞。
但是現在您必須使用Iterator來遍歷整個集合。

當然,您可以通過引入新的介面謂詞來模仿番石榴和Apache的做法。
這可能也是大多數高階開發人員將要做的事情。

然後我們可以使用下面的程式碼來過濾一個集合:

6. 將列表轉換為集合的最簡單方法?
有兩種方法可以這樣做,這取決於您希望如何定義等號。第一部分程式碼將一個列表放入一個HashSet中。
然後,重複主要由hashCode()標識。在大多數情況下,這是可行的。但是如果您需要指定比較的方式,最好使用第二段程式碼,其中可以定義自己的比較器。

7. 如何從ArrayList中刪除重複的元素?
這個問題和上面的問題有很大的關係。
如果您不關心ArrayList中元素的順序,一個聰明的方法是將列表放入一個集合中以刪除重複,然後將其移回列表中。下面是程式碼

如果您確實關心排序,那麼可以通過將一個列表放入標準JDK中的Linkedhashset中來保留順序。
8.分類收集
有幾種方法可以在Java中維護排序的集合。它們都以自然順序或通過指定的比較器提供了一個集合。通過自然排序,您還需要在元素中實現可比較的介面。
collections.sort()可以對列表進行排序。正如JavaDoc中指定的那樣,這種排序是穩定的,並保證n個日誌(n)的效能。
PriorityQueue提供有序佇列。priorityQueue和collections.sort()的區別在於priorityQueue始終維護一個訂單佇列,但只能從佇列中獲取head元素。您不能隨機訪問它的元素,如priorityqueue.get(4)。
如果集合中沒有重複項,則TreeSet是另一個選擇。與PriorityQueue相同,它始終維護有序集。你可以從樹集中得到最低和最高的元素。但您仍然不能隨機訪問它的元素。
總之,collections.sort()提供了一個一次性的有序列表。PriorityQueue和Treeset始終維護有序的集合,而不需要對元素進行索引訪問。
9.collections.emptylist()與新例項
同樣的問題也適用於emptymap()和emptyset()。
兩個方法都返回空列表,但collections.empty list()返回不可變的列表。這意味著您不能將新元素新增到“空”列表中。在後臺,每次呼叫collections.empty list()實際上不會建立空列表的新例項。相反,它將重用現有的空例項。如果你對設計模式很熟悉,你應該知道我的意思。因此,如果經常打電話,這將給您帶來更好的效能。
10 Collections.copy
有兩種方法可以將源列表複製到目標列表。一種方法是使用arraylist建構函式

另一個是使用collections.copy()(如下所示)。注意第一行,我們分配的列表至少與源列表一樣長,因為在集合的javadoc中,它表示目標列表必須至少與源列表一樣長。

這兩種方法都是膚淺的複製。那麼這兩種方法有什麼區別呢?
首先,collections.copy()不會重新分配dstlist的容量,即使dstlist沒有足夠的空間來包含所有srcList元素。相反,它將丟擲indexoutofboundsException。人們可能會質疑它是否有任何好處。一個原因是它保證了方法線上性時間內執行。另外,當您希望重用陣列而不是在arraylist的建構函式中分配新記憶體時,它也非常適合。
collections.copy()只能接受list作為源和目標,而arraylist接受collection作為引數,因此更通用。
最後,想學習Java的小夥伴們!
關注 “ 速學java ” 公眾號就可以拿到一份我為大家準備的Java學習資料!
對Java感興趣的小夥伴也可以加 小編V❤: suxuejava
