gpt4 book ai didi

Java 流 : How to do an efficient "distinct and sort"?

转载 作者:IT老高 更新时间:2023-10-28 20:47:23 25 4
gpt4 key购买 nike

假设我有一个 Stream<T>并且只想获取不同的元素并进行排序。

天真的方法是只做以下事情:

Stream.of(...)
.sorted()
.distinct()

或者,也许反过来:

Stream.of(...)
.distinct()
.sorted()

由于 JDK 的源代码无法真正访问它们的实现,我只是想知道可能的内存消耗和性能影响。

或者像下面这样编写我自己的过滤器会更有效吗?

Stream.of(...)
.sorted()
.filter(noAdjacentDuplicatesFilter())

public static Predicate<Object> noAdjacentDuplicatesFilter() {
final Object[] previousValue = {new Object()};

return value -> {
final boolean takeValue = !Objects.equals(previousValue[0], value);
previousValue[0] = value;
return takeValue;
};
}

最佳答案

当您在 sorted() 之后链接 distinct() 操作时,实现将利用数据的排序特性并避免构建内部 HashSet,可以通过下面的程序来演示

public class DistinctAndSort {
static int COMPARE, EQUALS, HASHCODE;
static class Tracker implements Comparable<Tracker> {
static int SERIAL;
int id;
Tracker() {
id=SERIAL++/2;
}
public int compareTo(Tracker o) {
COMPARE++;
return Integer.compare(id, o.id);
}
public int hashCode() {
HASHCODE++;
return id;
}
public boolean equals(Object obj) {
EQUALS++;
return super.equals(obj);
}
}
public static void main(String[] args) {
System.out.println("adjacent sorted() and distinct()");
Stream.generate(Tracker::new).limit(100)
.sorted().distinct()
.forEachOrdered(o -> {});
System.out.printf("compareTo: %d, EQUALS: %d, HASHCODE: %d%n",
COMPARE, EQUALS, HASHCODE);
COMPARE=EQUALS=HASHCODE=0;
System.out.println("now with intermediate operation");
Stream.generate(Tracker::new).limit(100)
.sorted().map(x -> x).distinct()
.forEachOrdered(o -> {});
System.out.printf("compareTo: %d, EQUALS: %d, HASHCODE: %d%n",
COMPARE, EQUALS, HASHCODE);
}
}

将打印出来

adjacent sorted() and distinct()
compareTo: 99, EQUALS: 99, HASHCODE: 0
now with intermediate operation
compareTo: 99, EQUALS: 100, HASHCODE: 200

map(x -> x)这样简单的中间操作,不能被Stream实现识别,因此,它必须假设元素可能不会根据映射函数的结果进行排序。

无法保证会发生这种优化,但是,可以合理地假设 Stream 实现的开发人员不会删除该优化,甚至会尝试添加更多优化,因此滚动您自己的实现会阻止您的代码受益于 future 的优化。

此外,您创建的是“有状态谓词”,强烈建议不要这样做,当然,在与并行流一起使用时会中断。

如果您不相信 Stream API 能够足够有效地执行此操作,那么最好在不使用 Stream API 的情况下实现此特定操作。

关于Java 流 : How to do an efficient "distinct and sort"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43806467/

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