You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

筛选ArrayList元素至新集合:两种方案优劣对比及优化建议

方案分析与优化建议

嘿,我来帮你拆解这两个方案的差异,再聊聊更合适的实现思路~

首先得先明确你的核心需求:你是要完全匹配invoice_no和invNumber完全相等,还是要包含匹配invoice_no中包含invNumber作为子串?这两个方案的逻辑本质是不一样的,先对齐需求再谈优劣:

1. 现有两个方案的差异与性能对比

  • 方案一(equals完全匹配):

    for (InvoiceSubData s : invProperty) { 
        if (invNumber.equals(s.getInvoiceNo())) { 
            newProperty.add(s); 
        } 
    }
    

    这个是严格匹配整个invoice_no字符串,逻辑精准(如果你的需求就是找完全相等的记录)。性能上,equals方法会先比较字符串长度,再逐字符匹配,一旦发现不匹配就终止,效率比子串查找高很多。

  • 方案二(contains包含匹配):

    for (InvoiceSubData s : invProperty) { 
        if (s.getInvoiceNo().contains(invNumber)) { 
            newProperty.add(s); 
        } 
    }
    

    这个是检查invoice_no是否包含invNumber作为子串,逻辑和方案一完全不同(比如invNumber是"INV123",那invoice_no是"INV123-001"也会被匹配)。性能上,contains需要做子串查找,开销比equals大,尤其是当字符串较长时差异更明显。

所以如果需求是完全匹配,方案一才是正确且更优的;如果是包含匹配,那方案二符合需求,但性能不如完全匹配场景。

2. 更简洁高效的替代方案(Java 8+)

如果你用的是Java 8及以上版本,推荐用Stream API实现,代码更简洁易读,性能和循环方式持平(JVM甚至会做底层优化):

完全匹配场景:

List<InvoiceSubData> newProperty = invProperty.stream()
    .filter(invoice -> invNumber.equals(invoice.getInvoiceNo()))
    .collect(Collectors.toList());

包含匹配场景:

List<InvoiceSubData> newProperty = invProperty.stream()
    .filter(invoice -> invoice.getInvoiceNo().contains(invNumber))
    .collect(Collectors.toList());

另外,如果你需要频繁根据invoice_no查询,可以提前把invProperty按invoice_no分组存入Map,后续查询直接取值,时间复杂度降到O(1):

// 仅需执行一次的分组操作
Map<String, List<InvoiceSubData>> invoiceGroupMap = invProperty.stream()
    .collect(Collectors.groupingBy(InvoiceSubData::getInvoiceNo));

// 后续查询直接获取对应列表
List<InvoiceSubData> newProperty = invoiceGroupMap.getOrDefault(invNumber, new ArrayList<>());

这个方式适合多次查询的场景,一次性分组的开销会被多次查询抵消,整体效率更高。

总结

  • 单次查询+完全匹配:方案一或Stream版本都可,Stream更简洁
  • 单次查询+包含匹配:方案二或对应Stream版本
  • 多次查询:提前分组到Map是最优解

内容的提问来源于stack exchange,提问作者D.Madu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:23:16