2015-01-12 8 views
14

ben gibi bir akışı vardır:Java8 Akışları - Farklı Stream ile çoğaltır çıkarın

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

Ben sadece bir isim başlayan (hangisi olduğu önemli değil), böylece aynı harfle başlayan isimler kaldırmak istiyoruz bu harfle kaldı.

distinct() yönteminin nasıl çalıştığını anlamaya çalışıyorum. Belgede, bir nesnenin "eşittir" yöntemini temel aldığını okudum. Ancak, dizeyi sarmalamayı denediğimde, eşit yöntemin hiçbir zaman çağrılmadığını ve hiçbir şeyin kaldırılmadığını fark ettim. Burada özlediğim bir şey mi var?

Sarıcı Sınıfı:

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

Ve bazı basit kodu: equals geçersiz zaman

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

Ben [Bu yanıt] anlatılan tekniği var (http://stackoverflow.com/a/27872086/1441122). (Cevabın sonuna kadar ilerleyin). Bu, filtreyi (distinctByKey (s -> s.charAt (0))) 'ın yapmasına izin verir. –

+6

Yan nota: Bir akışlar akışı için, Stream.of ("mat", "jason", "michael") 'ü kullanmak daha kolaydır. –

cevap

14

, ayrıca distinct() uygulanmasında kullanılacak hashCode() yöntemini geçersiz kılmak gerekir.

Bu durumda

, sadece iyi çalışacak

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

... kullanabilirsiniz.

+5

Evet, bu işe yarıyor. Bunu daha kolay hale getirmek için bir karşılaştırıcıyı "farklı" haline getirebilirseniz hoş olurdu. –

+4

İstediğiniz buysa, bunu bir TreeSet'e bırakabilirsiniz. –

+5

Haklısınız ... Bazen yeni bir çekiç aldığınızda her şey bir çivi gibi görünmeye başlar. ;-) –

5

Alternatif yaklaşım

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