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

Java ArrayList 查找對象索引:Stream API、迭代器、傳統循環三種方式對比

     編輯:程式設計綜合問答

在 List 中根據名字查找對象索引,是典型的「按屬性查找」場景。Java 8+ 推薦 Stream API,傳統循環最直觀,迭代器適用於並發修改場景。

實體類定義


class Person {
    private String name;
    private String sex;
    private int age;
    // 構造器、getters、setters、toString
    public Person(String name, String sex, int age) { ... }
    public String getName() { return name; }
}

方案一:Stream API (Java 8+ 推薦,函數式、可鏈式)


List list = Arrays.asList(
    new Person("張三", "男", 20),
    new Person("李四", "男", 22),
    new Person("王五", "男", 24)
);

// 返回 Optional,優雅處理未找到
Optional indexOpt = IntStream.range(0, list.size())
    .filter(i -> "李四".equals(list.get(i).getName()))
    .findFirst();

// 使用
indexOpt.ifPresentOrElse(
    index -> System.out.println("索引: " + index), // 輸出 1
    () -> System.out.println("未找到")
);

// 一行寫法 (不推薦生產,調試難)
int index = IntStream.range(0, list.size())
    .filter(i -> "李四".equals(list.get(i).getName()))
    .findFirst()
    .orElse(-1); // -1 表示未找到

方案二:傳統 for 循環 (效能最好、最易讀、調試友好)


int findIndexByName(List list, String targetName) {
    for (int i = 0; i < list.size(); i++) {
        if (targetName.equals(list.get(i).getName())) { // 防空指針用常量調用 equals
            return i;
        }
    }
    return -1; // 未找到
}

方案三:List.indexOf + 自定義 Predicate (Java 8 無原生支援,需工具類)


// Apache Commons Collections
int index = ListUtils.findIndex(list, p -> "李四".equals(p.getName()));

// 或自己寫通用工具
public static  int findIndex(List list, Predicate predicate) {
    for (int i = 0; i < list.size(); i++) {
        if (predicate.test(list.get(i))) return i;
    }
    return -1;
}

// 使用
int index = findIndex(list, p -> "李四".equals(p.getName()));

方案四:並行流 (大數據量、多核 CPU)


// 注意:並行流有開銷,小列表反而慢
int index = IntStream.range(0, list.size())
    .parallel() // 並行
    .filter(i -> "李四".equals(list.get(i).getName()))
    .findAny() // 並行用 findAny
    .orElse(-1);

效能與適用性對比

方案時間複雜度空間複雜度可讀性調試適用場景
for 循環O(n)O(1)⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐所有場景、熱路徑、嵌入式
Stream APIO(n)O(1) (鏈式)⭐⭐⭐⭐⭐⭐⭐業務邏輯、鏈式操作、函數式風格
工具類封裝O(n)O(1)⭐⭐⭐⭐⭐⭐⭐⭐⭐項目通用、團隊統一風格
並行流O(n/p)O(log n)⭐⭐⭐⭐⭐超大列表 (10萬+)、CPU 密集

進階:頻繁查找優化 - 建立索引 Map


// 如果頻繁按名字查找,構建 Map 索引 O(1) 查找
Map nameToIndex = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
    nameToIndex.put(list.get(i).getName(), i);
}

// 查找
Integer index = nameToIndex.get("李四"); // O(1)
// 注意:列表修改時需同步維護 Map

最佳實踐建議

  1. 首選 for 循環:簡單、快、無依賴、易調試、無自動裝箱開銷。
  2. 2. 團隊統一風格:封裝 CollectionUtils.findIndex(list, predicate) 通用方法。 3. 防空指針:"李四".equals(obj.getName()) 而非 obj.getName().equals("李四")。 4. 返回 -1 表示未找到:避免 Optional 在簡單邏輯中增加認知負荷。 5. 頻繁查詢建索引:Map/數據庫索引/搜索引擎,勿在列表線性掃描。

核心原則:正確性 > 可讀性 > 效能。對於百元級列表,for 循環是最佳平衡;萬級以上考慮索引優化。

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