Java 流和distinct操作
我有以下代码:Java 流和distinct操作,java,java-8,java-stream,Java,Java 8,Java Stream,我有以下代码: class C { String n; C(String n) { this.n = n; } public String getN() { return n; } @Override public boolean equals(Object obj) { return this.getN().equals(((C)obj).getN()); } } List<
class C
{
String n;
C(String n)
{
this.n = n;
}
public String getN() { return n; }
@Override
public boolean equals(Object obj)
{
return this.getN().equals(((C)obj).getN());
}
}
List<C> cc = Arrays.asList(new C("ONE"), new C("TWO"), new C("ONE"));
System.out.println(cc.parallelStream().distinct().count());
C类
{
字符串n;
C(字符串n)
{
这个,n=n;
}
公共字符串getN(){return n;}
@凌驾
公共布尔等于(对象obj)
{
返回这个.getN().equals(((C)obj.getN());
}
}
listcc=Arrays.asList(新C(“一”)、新C(“二”)、新C(“一”);
System.out.println(cc.parallelStream().distinct().count());
但是我不明白为什么
distinct
返回3而不是2。您还需要重写类C
中的hashCode
方法。例如:
@Override
public int hashCode() {
return n.hashCode();
}
当两个C
对象相等时,它们的hashCode
方法必须返回相同的值
接口流
的API文档没有提到这一点,但众所周知,如果覆盖等于
,那么还应该覆盖哈希代码
。Object.equals()
的API文档提到:
请注意,每当重写hashCode
方法时,通常需要重写该方法,以便维护hashCode
方法的一般约定,该约定规定相同的对象必须具有相同的哈希代码
显然,
Stream.distinct()
确实使用了对象的哈希代码,因为当您像上面所示那样实现它时,您会得到预期的结果:2。Aha,您正在试验Java 8。还可以尝试在类C
中重写hashCode()
。如果两个C
对象相等,则它们的哈希代码必须相同。在重写的equals
中放置一个断点,然后查看distinct
是否认为它是相等的。@Jesper,我在的文档中没有看到任何关于哈希代码
的担忧,但它似乎最初是在哈希代码
上运行的,因为这通常比equals
检查更有效。由于这是一个一般契约,两个相等的对象必须具有相同的散列。因此,当hashcode
s相同时,仅执行equals
检查是有效的解决方案。我相信这正是distinct
所做的,但我不明白为什么distinct
返回3而不是2。distinct
应该是count
。流实现可能在内部使用HashSet,它使用hashCode
方法。+1您提到的规则非常重要,不要重写equals或hashcode,除非同时重写这两个。这可能会导致编译时错误。