我有一个像这样的
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
对象列表,我想异步获取爱好的交集。我知道如何正常获取两个列表的交集,但我想以异步和多线程的方式进行此操作。我
你可以这样做:
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,所以在这种情况下,非常不清楚“异步”是什么意思。