提问者:小点点

比较两个列表并增加与java streams匹配的计数器


我有两份清单<代码>列表1包含一些城市。

列表2包含子列表。每个子列表包含一个人已经访问过的国家(一个子列表=一个人访问过的国家)。在这个例子中,Person1去了罗马、阿姆斯特丹和维也纳,Person2去了阿姆斯特丹、巴塞罗那和米兰。。。

我想知道有多少人已经去过第一个名单上的国家。不应重复计算。因此,如果人员1已经从列表1前往两个国家,则只应计算一次。

我想用JavaStreams实现这个。有人知道我怎么做吗?

list1 = ["Barcelona", "Milan", "Athens"];
list2 = [["Rom", "Amsterdam", "Vienna"], ["Amsterdam", "Barcelona", "Milan"], ["Prais", "Athens"], ["Istanbul", "Barcelona", "Milan", "Athens"]];

//The expected result for this example is: 3
//Both lists already result from a stream (Collectors.toList())

谢谢!


共2个答案

匿名用户

您可以尝试以下操作:

    private static final List<String> CITIES = List.of("Barcelona", "Milan", "Athens");
    private static final List<List<String>> VISITED_CITIES = List.of(
            List.of("Rome", "Amsterdam", "Vienna"),
            List.of("Amsterdam", "Barcelona", "Milan"),
            List.of("Paris", "Athens"),
            List.of("Instabul", "Barcelon", "Milan", "Athens")
    );

    public static void main(String... args) {
        var count = VISITED_CITIES
                .stream()
                .flatMap(visited -> visited.stream().filter(CITIES::contains))
                .distinct()
                .count();
        System.out.println(count);
    }

通过此迭代,您将得到预期的结果3。但是,您可以修改代码,也可以将其收集到一个将显示频率的映射中(如果删除“distinct”中间步骤),如下所示:

        var count = VISITED_CITIES
                .stream()
                .flatMap(visited -> visited.stream().filter(CITIES::contains))
                .collect(Collectors.groupingBy(Function.identity()));

匿名用户

请看一下mapToInt()和sum()函数。

List<String> list1 = List.of("Barcelona", "Milan", "Athens");
        List<List<String>> list2 = List.of(List.of("Rom", "Amsterdam", "Vienna"),
                                           List.of("Amsterdam", "Barcelona", "Milan"),
                                           List.of("Prais", "Athens"),
                                           List.of("Istanbul", "Barcelona", "Milan", "Athens"));
int result = list2.stream().mapToInt(person -> person.stream().anyMatch(list1::contains) ? 1 : 0).sum();

我在这里要做的是创建一个所有人的流,然后根据列表1中是否包含他们访问过的国家,将每个人映射到1或0。

这与以下for循环示例相同:

int result = 0;
for (List<String> person : list2)
{
    int i = 0;
    for (String visited : person)
    {
        if (list1.contains(visited))
        {
            i = 1;
            break;
        }
    }
    result += i;
}