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

Java List 模糊查詢實現方案:正則表達式與 Stream API 實戰

     編輯:Java 相關知識

前言

在內存中對 List 集合進行模糊查詢是常見需求。本文介紹兩種主流方案:基於正則表達式的傳統循環過濾,以及 Java 8+ Stream API 的函數式寫法,並對比性能與適用場景。

一、場景定義

class Employee {
    private String name; private int age;
    // getter/setter/toString 省略
}

List list = Arrays.asList(
    new Employee("wangqiang", 30),
    new Employee("lisi", 25),
    new Employee("zhangsan", 28)
);
// 需求:查詢名字包含 "wang" 的員工

二、方案一:正則表達式 + 循環過濾

1. 基礎版(區分大小寫,精確匹配)

public List search(String name, List list) {
    List result = new ArrayList<>();
    Pattern pattern = Pattern.compile(name); // 編譯正則
    for (Employee emp : list) {
        Matcher matcher = pattern.matcher(emp.getName());
        if (matcher.matches()) { // 整串匹配
            result.add(emp);
        }
    }
    return result;
}

2. 忽略大小寫

Pattern pattern = Pattern.compile(name, Pattern.CASE_INSENSITIVE);

3. 模糊匹配(關鍵:使用 find() 而非 matches())

if (matcher.find()) { // 子串匹配
    result.add(emp);
}

關鍵區別:matches() 要求整個字符串符合正則;find() 只要字符串中包含匹配子串即可。模糊查詢必須用 find()。

4. 通配符支持

若用戶輸入 wa*g 期望匹配 wang,需將 * 轉為正則 .*:

String regex = name.replace("*", ".*").replace("?", ".");
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

三、方案二:Stream API 函數式風格(推薦 Java 8+)

1. 基礎模糊查詢

public List searchStream(String keyword, List list) {
    return list.stream()
        .filter(emp -> emp.getName().toLowerCase().contains(keyword.toLowerCase()))
        .collect(Collectors.toList());
}

2. 正則模糊查詢

public List searchRegex(String regex, List list) {
    Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
    return list.stream()
        .filter(emp -> pattern.matcher(emp.getName()).find())
        .collect(Collectors.toList());
}

3. 並行流處理大數據量

return list.parallelStream() // 并行流
    .filter(emp -> emp.getName().contains(keyword))
    .collect(Collectors.toList());

四、方案三:第三方庫(Apache Commons Collections / Guava)


// Guava
List result = list.stream()
    .filter(Predicates.containsPattern(Pattern.compile(keyword, Pattern.CASE_INSENSITIVE)))
    .collect(Collectors.toList());

// Apache Commons Collections 4
Collection result = CollectionUtils.select(list, 
    emp -> emp.getName().toLowerCase().contains(keyword.toLowerCase()));

五、性能對比與選型建議

方案優點缺點適用場景
正則+循環靈活支持複雜正則;兼容舊版本代碼冗長;手動編譯 Pattern 易忘記複用需複雜正則規則;Java 7 環境
Stream API代碼簡潔;易並行;鏈式調用調試稍難;Lambda 序列化限制Java 8+ 通用首選
contains/ indexOf無正則開銷;速度最快不支持通配符/正則簡單子串匹配,極高性能要求
第三方庫豐富謂詞組合引入依賴已使用對應庫的項目

六、最佳實踐總結

  • 預編譯 Pattern:正則對象不可變,可靜態緩存或作為方法參數傳入,避免重複編譯。
  • 優先使用 String.contains:簡單子串查詢無需正則,性能提升 10 倍以上。
  • 大數據量考慮索引:若頻繁查詢同一字段,考慮構建 Map> 索引或使用內存數據庫(H2、SQLite)。
  • 並行流閾值:parallelStream 適合數萬條以上數據,小集合開銷反而更大。
  • 空值防護:emp.getName() 可能為 null,建議 Objects.toString(emp.getName(), "")。

選擇合適的工具,寫出既優雅又高效的查詢代碼。

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