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

Java 集合框架進階:LinkedList、ArrayList、HashSet 核心原理與實戰技巧

     編輯:Java 綜合教學

Java 集合框架進階:LinkedList、ArrayList、HashSet 核心原理與實戰技巧

集合框架是 Java 開發最高頻工具。本文基於經典教學案例,深度剖析 LinkedList、ArrayList、HashSet 的特有方法、底層數據結構、去重原理與最佳實踐,附帶完整可運行代碼。

一、LinkedList:雙向鏈表的靈活操作

LinkedList 實現 List、Deque 接口,底層為雙向鏈表,首尾增刪 O(1),隨機訪問 O(n)。

特有首尾操作方法

JDK 1.6 前 JDK 1.6+ 替代(推薦) 語義 空集合行為
addFirst/e offerFirst/e 頭部插入 無異常
getFirst/e peekFirst/e 獲取頭部(不移除) 前者拋 NoSuchElementException,後者返回 null
removeFirst/e pollFirst/e 獲取並移除頭部 同上

實戰:模擬棧與隊列

// 棧:先進後出 (LIFO) - 只操作頭部
class MyStack<E> {
    private LinkedList<E> list = new LinkedList<>();
    public void push(E e) { list.addFirst(e); }
    public E pop() { return list.removeFirst(); }
    public boolean isEmpty() { return list.isEmpty(); }
}

// 隊列:先進先出 (FIFO) - 頭部入,尾部出
class MyQueue<E> {
    private LinkedList<E> list = new LinkedList<>();
    public void offer(E e) { list.addFirst(e); }
    public E poll() { return list.removeLast(); }
    public boolean isEmpty() { return list.isEmpty(); }
}

二、ArrayList:動態數組的高效隨機訪問

ArrayList 底層為可擴容數組,隨機訪問 O(1),尾部插入均攤 O(1),中間增刪 O(n)。

去重算法:利用新集合 + contains 檢查

public static <E> List<E> distinct(List<E> source) {
    List<E> result = new ArrayList<>();
    for (E e : source) {
        if (!result.contains(e)) { // 依賴 equals()
            result.add(e);
        }
    }
    return result;
}

關鍵點:contains、remove 底層調用元素 equals(),**自定義對象必須重寫 equals()(通常也要重寫 hashCode())**。

自定義對象去重示例

class Person {
    private String name;
    private int age;
    // 構造器、getter...

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Person)) return false;
        Person p = (Person) o;
        return this.name.equals(p.name) && this.age == p.age;
    }
    // 生產環境必須重寫 hashCode(),保持與 equals 契約一致
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

三、HashSet:哈希表實現的唯一性集合

HashSet 底層封裝 HashMap,特點:**無序、不重複、允許一個 null**。

存儲機制:hashCode + equals 雙重判定

  1. 計算元素 hashCode(),定位桶位置
  2. 若桶為空 → 直接存入
  3. 若桶非空 → 遍歷桶中節點,調用 equals() 比較
  4. 全不相等 → 掛入鏈表/紅黑樹(JDK 8+)
  5. 存在相等 → 拒絕添加(add() 返回 false)

性能優化:優質 hashCode 實現

@Override
public int hashCode() {
    // 讓不同對象盡量分散,減少 equals 調用
    return name.hashCode() * 31 + age;
}

contains/remove 同理依賴 hashCode + equals

HashSet<Person> set = new HashSet<>();
set.add(new Person("Alice", 25));
set.contains(new Person("Alice", 25)); // true - 先算 hashCode 定位,再 equals 比較
set.remove(new Person("Alice", 25));   // true - 同上機制

四、完整代碼演示

import java.util.*;

public class CollectionDemo {
    public static void main(String[] args) {
        // 1. LinkedList 模擬棧
        LinkedList<String> stack = new LinkedList<>();
        stack.addFirst("A"); stack.addFirst("B"); stack.addFirst("C");
        while (!stack.isEmpty()) System.out.println(stack.removeFirst()); // C B A

        // 2. ArrayList 去重
        List<String> list = Arrays.asList("A", "B", "A", "C", "B");
        System.out.println(distinct(list)); // [A, B, C]

        // 3. HashSet 存自定義對象
        Set<Person> persons = new HashSet<>();
        persons.add(new Person("Tom", 20));
        persons.add(new Person("Tom", 20)); // 重複,不會添加
        persons.add(new Person("Jerry", 20));
        persons.forEach(p -> System.out.println(p.getName() + ":" + p.getAge()));
    }

    public static <E> List<E> distinct(List<E> source) {
        List<E> result = new ArrayList<>();
        for (E e : source) if (!result.contains(e)) result.add(e);
        return result;
    }
}

class Person {
    private String name; private int age;
    public Person(String n, int a) { name=n; age=a; }
    public String getName() { return name; }
    public int getAge() { return age; }
    @Override public boolean equals(Object o) {
        if(!(o instanceof Person)) return false;
        Person p=(Person)o; return name.equals(p.name) && age==p.age;
    }
    @Override public int hashCode() { return Objects.hash(name, age); }
}

五、選型決策表

場景 推薦集合 理由
頻繁隨機訪問、尾部增刪 ArrayList 數組底層,get/set O(1)
頻繁首部/中間增刪、實現棧/隊列 LinkedList 鏈表底層,首尾增刪 O(1)
去重、集合運算(交/並/差)、無序可接受 HashSet 哈希表,add/contains/remove 平均 O(1)
有序去重、範圍查詢 TreeSet 紅黑樹,天然有序
保持插入順序去重 LinkedHashSet 鏈表+哈希表,有序且高性能

六、總結

  • LinkedList 適合首尾操作密集場景,offer/peek/poll 系列方法更安全。
  • ArrayList 去重依賴 equals(),自定義類必須正確重寫 equals/hashCode。
  • HashSet 通過 hashCode 定位 + equals 精確比較保證唯一性,優質 hashCode 是性能關鍵。
  • 集合框架設計精妙體現於接口抽象、實現解耦、算法複用,深入理解底層機制能寫出更高效、健壯的代碼。

代碼示例圖標

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