首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

【Simple Java】Java 集合框架 10 大高頻面試題深度解析

     編輯:Java 綜合教學

【Simple Java】Java 集合框架 10 大高頻面試題深度解析

以下整理自 StackOverflow 高頻問題,建議先閱讀《Java 集合框架接口與類層次結構圖》建立整體認知。

1. 何時選 LinkedList 而非 ArrayList?

ArrayList:底層動態數組,get(index) O(1);擴容與插入/刪除需搬移元素,O(n)。
LinkedList:雙向鏈表,隨機訪問 O(n);插入/刪除只改指針,O(1)。

| 操作              | ArrayList | LinkedList |
|-------------------|-----------|------------|
| get(index)        | O(1)      | O(n)       |
| add(E)            | O(n)      | O(1)       |
| add(E, index)     | O(n)      | O(n)       |
| remove(index)     | O(n)      | O(n)       |
| Iterator.remove() | O(n)      | O(1)       |
| Iterator.add(E)   | O(n)      | O(1)       |

記憶體方面:LinkedList 每節點額外兩指針,ArrayList 僅需數組。大列表時 ArrayList 更省內存。詳細對比見《ArrayList vs LinkedList vs Vector》。

2. 迭代時正確刪除元素

唯一正確方式:Iterator.remove()

Iterator<Integer> itr = list.iterator();
while (itr.hasNext()) {
    // do something
    itr.remove();
}

錯誤示範:for (Integer i : list) { list.remove(i); } → 拋 ConcurrentModificationException。原因:for-each 隱式生成迭代器,同時修改列表違反單線程迭代器修改規則。

3. List<Integer> 轉 int[]

Apache Commons Lang(推薦):

int[] array = ArrayUtils.toPrimitive(list.toArray(new Integer[0]));

純 JDK:

int[] array = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
    array[i] = list.get(i);
}

注意:List.toArray() 返回 Integer[],不可直接轉 int[]。

4. int[] 轉 List<Integer>

Apache Commons Lang:

List<Integer> list = Arrays.asList(ArrayUtils.toObject(array));

純 JDK:

List<Integer> list = new ArrayList<>();
for (int i : array) list.add(i);

5. 過濾集合最佳方式

第三方庫:Guava Collections2.filter()、Apache CollectionUtils.filter()。
JDK 8+:Predicate + Stream API。
JDK 7-:手動迭代器遍歷 + itr.remove()。

// 自定義 Predicate 模仿 Guava
public interface Predicate<T> { boolean test(T o); }
public static <T> void filter(Collection<T> c, Predicate<T> p) {
    if (c != null && p != null) {
        Iterator<T> itr = c.iterator();
        while (itr.hasNext()) if (!p.test(itr.next())) itr.remove();
    }
}
// 使用
filter(list, new Predicate<Integer>() {
    public boolean test(Integer i) { return i <= 5; }
});

6. List 轉 Set 最簡單方法

兩種語義:

  • HashSet:按 hashCode()/equals() 去重,適用大多數場景
  • TreeSet + Comparator:自定義相等判斷邏輯
Set<Integer> set = new HashSet<>(list);
// 或
Set<Integer> set = new TreeSet<>(comparator);
set.addAll(list);

7. ArrayList 去重

不保留順序:

Set<Integer> set = new HashSet<>(list);
list.clear();
list.addAll(set);

保留順序:用 LinkedHashSet 替換 HashSet。

8. 集合排序方式

  • Collections.sort(list):一次性排序,穩定 O(n log n),需元素實現 Comparable
  • PriorityQueue:始終有序,但只能訪問隊頭/尾,不支援隨機訪問
  • TreeSet:無重複 + 始終有序,同樣不支援隨機訪問

選擇建議:一次性排序用 Collections.sort();持續維持有序且不需隨機訪問,用 PriorityQueue 或 TreeSet。

9. Collections.emptyList() vs new ArrayList()

Collections.emptyList() 返回不可變單例空列表,頻繁調用不創建新對象,性能更優;new ArrayList() 每次創建新可變實例。同理適用於 emptyMap()、emptySet()。

10. Collections.copy() vs ArrayList 建構子

// 方式一
ArrayList<Integer> dst = new ArrayList<>(src);
// 方式二
ArrayList<Integer> dst = new ArrayList<>(src.size());
Collections.copy(dst, src);

區別:

  • Collections.copy():目標容量不足拋 IndexOutOfBoundsException,不擴容;參數僅限 List
  • ArrayList(Collection):自動擴容;接受任意 Collection,更通用

兩者均為淺拷貝。


原文鏈接:programcreek.com

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved