web-dev-qa-db-ja.com

ストリームと個別の操作

私は次のコードを持っています:

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が2ではなく3を返す理由がわかりません。

30
xdevel2000

クラスhashCodeCメソッドもオーバーライドする必要があります。例えば:

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

2つのCオブジェクトが等しい場合、それらのhashCodeメソッドは同じ値を返す必要があります。

インターフェイスStreamのAPIドキュメントではこれについて言及していませんが、equalsをオーバーライドする場合は、hashCodeもオーバーライドする必要があることはよく知られています。 Object.equals()のAPIドキュメントにはこれが記載されています。

通常、このメソッドがオーバーライドされるたびにhashCodeメソッドをオーバーライドする必要があることに注意してください。これは、等しいオブジェクトが等しいハッシュコードを持たなければならないことを示すhashCodeメソッドの一般規約を維持するためです。

どうやら、Stream.distinct()は実際にオブジェクトのハッシュコードを使用します。これは、上で示したように実装すると、期待される結果が得られるためです。

46
Jesper