gpt4 book ai didi

java - 试图理解 Java8 中流的 distinct()

转载 作者:搜寻专家 更新时间:2023-11-01 02:22:52 27 4
gpt4 key购买 nike

我正在阅读一本关于 Java8 的书,其中解释了流的 distinct。提到为了产生不同的元素,相等性是由 hashCode()equals() 方法的实现决定的。因此我写了下面的代码来理解示例:

static class Order{
public Order(int id,Double value){
this.id = id;
this.value = value;
}
int id;
Double value;
@Override
public int hashCode() {
System.out.println("In Hashcode() - " + this.id +","+this.value);
return this.id;
}
@Override
public boolean equals(Object o){
System.out.println("In Equals()");
return this.id == ((Order)o).id;
}
}

public static void main(String[] args) {
Stream<Order> orderList = Stream.of(new Order(1,10.0),new Order(2,140.5),new Order(2,100.8));
Stream<Order> biggerOrders = orderList.filter(o->o.value > 75.0);
biggerOrders.distinct().forEach(o->System.out.println("OrderId:"+ o.id));
}

它产生了以下输出:

In Hashcode() - 2,140.5
In Hashcode() - 2,140.5
OrderId:2
In Hashcode() - 2,100.8
In Equals()

我很困惑为什么同一个 Order 对象上的 hashCode 方法 (2,140.5)在将它与另一个订单对象 (2,100.8) 进行比较之前被调用两次。

提前致谢。

最佳答案

正如@Adi 所回答的,distinct() 在内部使用了一个 HashMap,它调用了 OrderhashCode()

这是进行这两个调用的相关代码

java.util.stream.DistinctOps.makeRef()

return new Sink.ChainedReference<T, T>(sink) {
Set<T> seen;

@Override
public void begin(long size) {
seen = new HashSet<>();
downstream.begin(-1);
}

@Override
public void end() {
seen = null;
downstream.end();
}

@Override
public void accept(T t) {
if (!seen.contains(t)) {//first call is made here
seen.add(t);//second call is made here
downstream.accept(t);
}
}
};

以下是这两个调用的堆栈跟踪。

enter image description here enter image description here

关于java - 试图理解 Java8 中流的 distinct(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34562359/

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