2015-01-12 16 views
14

私は、次のような流れを持っている:Java8ストリームは - 個別ストリームに重複を削除

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

私は1つの名前のみが始まる(これは問題ではない)ように、同じ文字で始まる名前を削除したいですその手紙は残されています。

私はdistinct()メソッドの仕組みを理解しようとしています。私はオブジェクトの "equals"メソッドに基づいていることをドキュメントで読みました。しかし、文字列をラップしようとすると、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); 
} 
+2

私は、[この回答](http://stackoverflow.com/a/27872086/1441122)に記載の技術があります。 (答えの最後までスクロールします)。これにより 'filter(distinctByKey(s - > s.charAt(0)))'を行うことができます。 –

+6

サイドノート:リテラルのストリームのために、 'Stream.of(" matt "、" jason "、" michael ")'を使う方がしばしばです。 –

答えて

14

あなたがequalsをオーバーライドするたび、あなたはまたdistinct()の実装で使用されますhashCode()メソッドをオーバーライドする必要があります。この場合

、あなただけうまく動作することになる...

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

を使用することができます。

+5

ええ、これはうまくいくようです。コンパレータを 'distinct'に渡してこれを少し簡単にすることができればいいと思います。 –

+4

それがあなたが望むならば、 'TreeSet'にダンプするだけです。 –

+5

あなたは正しい...ときには新しいハンマーが手に入ると、すべてが爪のように見えるようになります。 ;-) –

5

代替アプローチ

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); 
関連する問題