试图理解 Java8 中流的 distinct()
Trying to understand distinct() for streams in Java8
我正在阅读一本关于 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)
在与另一个 Order Object(2,100.8) 比较之前被调用两次。
提前致谢。
第一次调用 hashCode 来检查项目(订单)是否已经存在于 HashMap 中(distinct 使用内部 HashMap)。如果不存在,第二次调用将项目(订单)放入哈希图中。
提示:尝试调试 hashCode 方法。
正如@Adi 所回答的那样,distinct()
正在内部使用 HashMap,它调用 Order
的 hashCode()
。
这是进行这两个调用的相关代码
在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);
}
}
};
以下是这两个调用的堆栈跟踪。
我正在阅读一本关于 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) 在与另一个 Order Object(2,100.8) 比较之前被调用两次。
提前致谢。
第一次调用 hashCode 来检查项目(订单)是否已经存在于 HashMap 中(distinct 使用内部 HashMap)。如果不存在,第二次调用将项目(订单)放入哈希图中。
提示:尝试调试 hashCode 方法。
正如@Adi 所回答的那样,distinct()
正在内部使用 HashMap,它调用 Order
的 hashCode()
。
这是进行这两个调用的相关代码
在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);
}
}
};
以下是这两个调用的堆栈跟踪。