web-dev-qa-db-ja.com

Java8 Streams-ストリームが異なる重複を削除する

次のようなストリームがあります:

_Arrays.stream(new String[]{"matt", "jason", "michael"});
_

同じ文字で始まる名前を削除して、その文字で始まる名前を1つだけ(どちらでも構いません)残すようにします。

distinct() メソッドの仕組みを理解しようとしています。私はそれがオブジェクトの「等しい」メソッドに基づいていることをドキュメントで読みました。ただし、文字列をラップしようとすると、equalsメソッドが呼び出されず、何も削除されないことがわかります。ここに欠けているものはありますか?

ラッパークラス:

_static class Wrp {
    String test;
    Wrp(String s){
        this.test = s;
    }
    @Override
    public boolean equals(Object other){
        return this.test.charAt(0) == ((Wrp) other).test.charAt(0);
    }
}
_

そして、いくつかの簡単なコード:

_public static void main(String[] args) {
    Arrays.stream(new String[]{"matt", "jason", "michael"})
    .map(Wrp::new)
    .distinct()
    .map(wrp -> wrp.test)
    .forEach(System.out::println);
}
_
26
Matt Klooster

equalsをオーバーライドするときは常に、hashCode()の実装で使用されるdistinct()メソッドもオーバーライドする必要があります。

この場合、あなたはただ使うことができます

@Override public int hashCode() {
   return test.charAt(0);
}

...これで問題なく動作します。

20
Louis Wasserman

代替アプローチ

    String[] array = {"matt", "jason", "michael"};
    Arrays.stream(array)
            .map(name-> name.charAt(0))
            .distinct()
            .map(ch -> Arrays.stream(array).filter(name->name.charAt(0) == ch).findAny().get())
            .forEach(System.out::println);
17
Sujit Kamthe