首页 > 解决方案 > 使用 java 流比较两个字符串列表

问题描述

如何使用 Java Streams 执行以下操作?

在这里,我试图比较两个字符串列表。如果任何元素匹配,在第一个匹配中,增加计数,将匹配值添加到 matchList 并打破循环。

List<String> nameList1 = Arrays.asList("Bill", "Steve", "Mark");
List<String> nameList2 = Arrays.asList("Steve Jobs", "Mark", "Bill");

int count = 0;
List<String> matchList = new ArrayList<>();

for (String name1 : nameList1) {
    if (nameList2.contains(name1)) {
            count++;
            matchList.add(name1);
            break;
        }
    }
}

System.out.println(count); // 1
System.out.println(matchList); // [Bill]

标签: javajava-stream

解决方案


首先,现有的带有循环的解决方案就可以了。简单地将其转换为使用流的解决方案并不是一种改进。

这就是我将如何做到的。注意:这未经测试。

// Naive version

List<String> nameList1 = Arrays.asList("Bill", "Steve", "Mark");
List<String> nameList2 = Arrays.asList("Steve Jobs", "Mark", "Bill");

List<String> matchList = nameList1.stream()
    .filter(nameList2::contains)
    .limit(1)
    .collect(Collectors.toList());

count = matchList.size();

请注意,无需追加到列表增加计数。

如果您要尝试并行化此操作,则流可能会有所帮助,但您需要以不同的方式进行操作。

最后,如果你真的很关心性能,并且nameList2.size() == N足够大,那么转换nameList2HashSet. 这将其从O(MN)算法转变为O(M)算法。

(相比之下,并行化朴素版本最多只会给您带来O(MN/P)复杂性其中 P 是进程数。这是做出一些假设,并忽略潜在的内存争用效应。)


推荐阅读