java - 如何过滤 2 个巨大的列表,其中包含数百万个具有相同 ID 的项目

标签 java list java-stream

这是我的 2 列表,其中包含超过数百万个项目。两者都具有相同 ID 的相同项目。 ID 在字符串中。我只需要 ID 不同的项目。我就是这样做的。但我相信一定有更好的解决方案并且具有很高的持久性:-

    List<Transaction> differentList = new ArrayList<>();

    for(Transaction tx : foundTransactions ){
        for(Transaction aTx : ArchivedTransactions) 
        {
            if(!tx.getId().equalsIgnoreCase(aTx.getId()) ){
                differentList .add(tx);
            }
        }
    }

我尝试使用流,但我做不到。我想使用流 API 应该会更好。请向我提出任何改进建议。

最佳答案

您可以先尝试将其转换为 HashMap,类似于:

Set<String> collect = ArchivedTransactions.stream().map(i -> i.getId().toLowerCase())
                                           .collect(Collectors.toSet());

for(Transaction tx : foundTransactions )
    if(!collect.contains(tx.getId()))
       differentList.add(tx);

Collectors.toSet() 返回一个HashSet。您可以将代码简化为:

Set<String> collect = ArchivedTransactions.stream().map(i -> i.getId().toLowerCase())
                                          .collect(Collectors.toSet());

List<Transaction> differentList = foundTransactions.stream()
                                                   .filter(tx -> !collect.contains(tx.getId()))
                                                   .collect(Collectors.toList())

首先将 IDs 添加到 HashSet 作为中间步骤,这将为您提供更好的整体复杂性时间,因为 (source):

Time Complexity of HashSet Operations: The underlying data structure for HashSet is hashtable. So amortize (average or usual case) time complexity for add, remove and look-up (contains method) operation of HashSet takes O(1) time.

因此,"HashMap"解决方案的整体时间复杂度将是O(N + M),其中 NM 分别开始列表 ArchivedTransactionsfoundTransactions 中的元素数量。尽管如此,space-wise你将付出额外结构的代价。

您的解决方案 space-wise 更好,但时间复杂度最差。如果 N = M 您的解决方案的时间复杂度是 O(N^2),而具有 HashSet 的解决方案将是 O(2N),因此 O(N)。这是一个巨大的差异。

只做

Set<Transaction> result = new LinkedHashSet<>();
result.addAll(foundTransactions);
result.addAll(ArchivedTransactions);

单独将不起作用,因为您明确要求:

!tx.getId().equalsIgnoreCase(aTx.getId())

关于java - 如何过滤 2 个巨大的列表,其中包含数百万个具有相同 ID 的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65143461/

相关文章:

java - 将元素列表的列表转换为 Map < K, List<V>>

java - Java 中的对象输出流

c++ - 表达式 : cannot increment value-initialized iterator (Error in Debug, 但不在 Release模式下 - Visual Studio)

python - 如何在 python 中创建多个空的嵌套列表

python - 当我组合一类数据并分配给一个列表时,Python 中的 [...] 是什么意思?

Java 11 根据枚举值选择一种方法应用于流

c# - 针对多种编程语言/平台

java - 在 .property 中存储日期并与当前日期进行比较

java - 不使用泛型的ArrayList java程序

java - 使用 Stream API 将两个集合与谓词组合