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,除非同时重写这两个。这可能会导致编译时错误。