2014-01-24 71 views
24

我有以下代碼:流和不同的操作

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()); 

,但我不明白爲什麼distinct返回3而不是2

+3

啊哈,你與Java 8.嘗試嘗試還要在'C'類中重寫'hashCode()'。如果兩個'C'對象相等,則它們的哈希碼必須相同。 – Jesper

+1

在overrided'equals'中放置一個斷點,看看是否'distinct'。 –

+0

@Jesper,在http://download.java.net/jdk8/docs/api/java/util/stream/Stream.html#distinct- –

回答

34

您還需要重寫hashCode方法C類。例如:

@Override 
public int hashCode() { 
    return n.hashCode(); 
} 

當兩個C對象是相等的,它們的hashCode方法必須返回相同的值。

接口Stream的API文檔沒有提到這一點,但衆所周知,如果覆蓋equals,則應該覆蓋hashCode。對於Object.equals() API文檔提到了這一點:

注意,一般需要覆蓋hashCode方法每當這個方法被覆蓋,以保持對hashCode方法,其中指出相等的對象必須具有一般合同相同的哈希碼。

顯然,Stream.distinct()的確使用對象的哈希碼,因爲當你實現它就像我上面顯示,你得到預期的結果:2