如何使用Java 8 Lambda表达式遍历两个流并保持计数

3

我有两个列表流,一个是字符串列表(counties),另一个是对象列表(txcArray)。我需要遍历这两个列表,并比较 counties 实例和 txcArray 实例是否匹配,如果匹配,则增加计数器,如果不匹配,则继续。我需要使用 Java 8 lambda 表达式来实现这个功能,以下是我的代码。

counties.stream().forEach(a-> {
     txcArray.stream()
             .filter(b->b.getCounty().equals(a))
             .map(Map<String,Integer>)
});

1
我认为你的意思是:你有“两个列表”,而不是“两个列表流”?所以你只想计算你字符串列表中有多少项与对象数组中的谓词匹配?如果是这样的话:先忘掉.forEach,尝试使用.filter.count()解决它。如果它起作用了,你可以继续使用.map将你的对象转换成一个国家字符串再进行过滤。最后,你甚至可能想尝试使用方法引用。我不会从Grisha的建议开始使用zip,因为它似乎对于你要解决的问题来说更加复杂。 - Roland
让我再重新阐述问题。我有一个字符串类型的列表和另一个名为texasCitiesClass(txcArray)的列表。texasCitiesClass包含城市名称、县和人口。我在counties列表中拥有所有唯一的县。我需要做的是检查每个县在txcArray中出现的次数,并将此数字添加到另一个整数或长整型列表中,以表示每个县的数量。约束条件是我只能使用流和lambda表达式来完成这个任务。谢谢你们的帮助,Grisha和Roland。 - Octavio garcia
1个回答

6

你的错误在于使用了 forEach


List<Long> counts = counties.stream()
    .map(a -> txcArray.stream().filter(b -> b.getCounty().equals(a)).count())
    .collect(Collectors.toList());

然而,这种方法的效率并不高,会执行 counties.size() × txcArray.size() 次操作。当列表很大时,这种方法很容易失控。

更好的方法是使用

Map<String, Long> map = txcArray.stream()
    .collect(Collectors.groupingBy(b -> b.getCounty(), Collectors.counting()));
List<Long> counts = counties.stream()
    .map(a -> map.getOrDefault(a, 0L))
    .collect(Collectors.toList());

这将执行counties.size() + txcArray.size()次操作,对于较大的列表来说更加高效,因此更可取,即使它不是单个流操作,而是使用中间存储。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接