Java中如何使用异步和多线程获取列表列表的交集

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

我有一个像这样的

Person
课程:

public class Person {
    public String name;
    public List<String> hobbies;


    public Person(String name, List<String> hobbies) {
        this.name = name;
        this.hobbies = hobbies;
    } 
    //setter and getter
}

现在假设我有一个

Person
对象列表,我想异步获取爱好的交集。我知道如何正常获取两个列表的交集,但我想以异步和多线程的方式进行此操作。我

java asynchronous java-stream
1个回答
1
投票

你可以这样做:

List<Person> persons = new ArrayList<>();
persons.add(new Person("hatef", Arrays.asList("a", "b", "c", "t")));
persons.add(new Person("hatef", Arrays.asList("a", "b", "t")));
persons.add(new Person("hatef", Arrays.asList("t", "a", "b")));
persons.add(new Person("hatef", Arrays.asList("a", "b", "f", "t")));
persons.add(new Person("hatef", Arrays.asList("a", "t", "b", "z")));

然后使用

CompletableFuture

Map<String, Integer> all = new ConcurrentHashMap<>();
ExecutorService executorService = Executors.newFixedThreadPool(Math.max(10, persons.size()));
persons
        .stream()
        .map(person -> CompletableFuture.supplyAsync(() -> person, executorService))
        .map(p -> p.thenApply(Person::getHobbies))
        .map(p -> p.thenAccept(hobbies -> hobbies.forEach(hobby -> all.compute(hobby, (key, value) -> value == null ? 1 : ++value))))
        .map(CompletableFuture::join)
        .forEach(x -> {}); // just dummy consumer to make stream triggers

int n = persons.size();
Set<String> result = all
            .entrySet()
            .stream()
            .filter(entry -> entry.getValue() == n)
            .map(Map.Entry::getKey)
            .collect(Collectors.toSet());
System.out.println(result);

结果是:

[a, b, t]

如果你的爱好列表中有顺序,我认为你可以使用最长公共前缀问题的想法,而且它很有效

我同意@JoachimSauer的评论

您能解释一下异步到底是什么意思吗?通常这仅适用于任何类型的 I/O 操作(从磁盘读取、网络请求等),其中 CPU 不努力工作,但您仍然花费大量时间等待某些事情。这里的这种工作纯粹是 CPU/内存的工作,实际上不涉及任何 I/O,所以在这种情况下,非常不清楚“异步”是什么意思。

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