2015-01-12 17 views
14

Tôi có một dòng như:Java8 Streams - Hủy bỏ Duplicates Với Suối biệt

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

Tôi muốn đề nghị xóa tên đó bắt đầu bằng chữ tương tự như vậy mà chỉ có một tên (không quan trọng mà) bắt đầu với lá thư đó còn lại.

Tôi đang cố gắng hiểu cách thức hoạt động của phương thức distinct(). Tôi đọc trong tài liệu hướng dẫn dựa trên phương thức "bằng" của một đối tượng. Tuy nhiên, khi tôi thử gói String, tôi nhận thấy rằng phương thức equals không bao giờ được gọi và không có gì được loại bỏ. Có cái gì tôi đang thiếu ở đây?

Wrapper Class:

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

Và một số mã đơn giản:

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

Có kỹ thuật tôi đã mô tả trong [câu trả lời này] (http://stackoverflow.com/a/27872086/1441122). (Cuộn đến cuối câu trả lời). Điều này sẽ cho phép bạn làm 'filter (distinctByKey (s -> s.charAt (0)))'. –

+6

Lưu ý phụ: đối với luồng chữ, thường dễ sử dụng 'Stream.of (" matt "," jason "," michael ")'. –

Trả lời

14

Bất cứ khi nào bạn ghi đè equals, bạn cũng cần phải ghi đè lên các phương pháp hashCode(), mà sẽ được sử dụng trong việc thực hiện distinct().

Trong trường hợp này, bạn chỉ có thể sử dụng

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

... mà sẽ chỉ làm việc tốt.

+5

Vâng, điều này dường như hoạt động. Nó sẽ là tốt đẹp nếu bạn có thể vượt qua một so sánh vào 'khác biệt' để làm cho điều này một chút dễ dàng hơn. –

+4

Nếu đó là những gì bạn muốn, bạn chỉ có thể đổ nó vào một 'TreeSet'. –

+5

Bạn đúng ... Đôi khi bạn nhận được một cái búa mới, mọi thứ bắt đầu trông giống như một cái đinh. ;-) –

5

cách tiếp cận thay thế

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