gpt4 book ai didi

java - 使用流过滤集合以获取其属性在 Java 8 中出现 n 次的项目

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:16:55 25 4
gpt4 key购买 nike

假设我有一个 Person(name, age) 对象的集合:

Set<Person> people = new HashSet<Person>();
people.add(new Person("Peter", 26));
people.add(new Person("Dane", 24));
people.add(new Person("Gregory", 26));
people.add(new Person("Daniel", 27));
people.add(new Person("Micheal", 27));
people.add(new Person("David", 26));
people.add(new Person("Kate", 21));

people.forEach(i -> System.out.println(i.getName()));

现在我想检查是否有三个年龄相同的人,或者是否有一对同名的人,并将这些人放在另一个列表中。所以我写了下面的通用静态方法:

private static <T> Collection<T> filterWhenMultipleOccurance(Collection<T> collection,
Function<T, ?> comparisonCriteria, int demandedOccuranceAmount) {
return collection.stream()
.filter(item -> collection.stream()
.filter(otherItem ->
comparisonCriteria.apply(otherItem) == comparisonCriteria.apply(item))
.toArray().length == demandedOccuranceAmount)
.collect(Collectors.toList());
}

现在我可以调用这个方法来满足我的需求:

Collection<Person> selectedPeople = filterWhenMultipleOccurance(people, p -> p.getAge(), 3);
System.out.println("---------------");
selectedPeople.forEach(p -> System.out.println(p.getName()));

这让我得到了由 Peter、Gregory 和 David 组成的正确列表。

我觉得这个解决方案既不优雅也不高效,因为我嵌套了 stream().filter 调用,所以我假设时间复杂度至少为 O(n^2)。这个问题有更好的解决方案吗?

最佳答案

我认为你最好使用 groupingBy收集器,根据您作为参数提供的功能对元素进行分类。这会给你一个 Map<Object, List<T>> .

从那里再次从条目集中获取流。由于您对键不感兴趣,您将每个条目映射到它的值(List<T>)并过滤具有适当大小的列表。最后,您再次将元素收集到一个列表中(在对列表进行平面映射之后),结果是 List<T>。 .

private static <T> Collection<T> filterWhenMultipleOccurance(Collection<T> collection,
Function<T, ?> comparisonCriteria,
int demandedOccuranceAmount) {
return collection.stream()
.collect(groupingBy(comparisonCriteria))
.values()
.stream()
.filter(l -> l.size() >= demandedOccuranceAmount)
.flatMap(List::stream)
.collect(toList());
}

在流中每个项目的原始解决方案中,您再次过滤集合的所有元素。所以基本上你在做不必要的操作,因为一旦你过滤了一个满足要求的项目,你就知道每个具有相同属性的项目给定比较函数都会产生相同的结果。

你也在使用 ==comparisonCriteria.apply(otherItem) == comparisonCriteria.apply(item)这可能不起作用,因为您正在比较引用文献(我想这不是您想要的)。

最后你是在浪费内存,因为你创建了一个数组来调用 .length .您可以使用 count()直接在这种情况下。

关于java - 使用流过滤集合以获取其属性在 Java 8 中出现 n 次的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34167870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com