使用 Java Stream API 计算包含另一个列表中的元素的列表数量

问题描述 投票:0回答:3

我有两个清单。

list1
包含一些城市。

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

我想知道有多少人去过第一个列表中的城市。不应出现重复计算。所以如果Person1已经从

list1
到过两个城市,就只算一次。

我想使用 Java Stream API 来实现这一点。有谁知道我该怎么做?

list1 = ["Barcelona", "Milan", "Athens"];
list2 = [["Rome", "Amsterdam", "Vienna"], ["Amsterdam", "Barcelona", "Milan"], ["Paris", "Athens"], ["Istanbul", "Barcelona", "Milan", "Athens"]];

//The expected result for this example is: 3
//Both lists already result from a stream (Collectors.toList())
java count java-stream compare
3个回答
0
投票

你可以尝试这样的事情:

    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。但是,您可以修改代码以也收集到将显示频率的

Map
中(如果删除
distinct
中间步骤),如下所示:

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

0
投票

看看

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 或 0,具体取决于他们访问过的国家/地区是否包含在 list1 中。

这与以下 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;
}

0
投票
long count = list2.stream()
        .filter(c -> !Collections.disjoint(list1, c))
        .count();

这会迭代每个人的城市列表,仅过滤掉去过第一个列表中城市的人,然后返回剩余过滤元素的计数。

© www.soinside.com 2019 - 2024. All rights reserved.