2017-04-25 4 views
0

私は書籍のリストを持っています。ラムダを使ってオブジェクトフィールドの重複数をどのように数えることができますか?

final List<Book> books = new ArrayList<>(); 
books.add(new Book(50, "Book1", 1997)); 
books.add(new Book(110, "Book2", 1998)); 
books.add(new Book(150, "Book3", 1999)); 
books.add(new Book(200, "Book4", 2000)); 
books.add(new Book(250, "Book1", 2001)); 

タイトルごとに重複を数えようとしました。

final Integer countDuplicates = books.stream() 
    .filter(b -> Collections.frequency(books, b.getTitle()) > 1) 
    .collect(Collectors.toList()).size(); 

しかし、動作しません。お願い助けて。

+0

[mcve]を入力してください。特に、私はBookクラスで 'equals'を実装していないと思われますが、コードを表示していません。 – assylias

+0

私はデフォルトのEclipse自動生成ツールでequalsとhashCodeを実装しました。これは常に十分でした – Comfmore

+0

"それは動作しません"あなたが直面している問題の有用な説明ではありません。期待したことと何が起こったのかを説明できますか? –

答えて

1

frequencyメソッドを誤って使用しています - 書籍のコレクションを渡して本や文字列のコレクションを探して文字列を検索する必要がありますが、現時点では書籍のコレクションを渡して探します文字列は - そう、それは常に返します0

一つの方法は、次のようになります。

Map<String, Long> frequency = books.stream() 
    .map(Book::getTitle) 
    .collect(Collectors.groupingBy(s -> s, Collectors.counting())); 

キーは、タイトルと値周波数あるマップを返します。

あなたは重複をカウントしたい場合は、あなたが行うことができます:

long duplicates = frequency.values().stream().filter(f -> f >= 2).count(); 
+0

入手しました。ありがとうございます。 – Comfmore

0

セットを作成し、セットからリストのサイズを引きます。適切なコンパレータを使用して重複を検出するようにしてください。

2

あなたが遭遇する問題はb.getTitle()は、あなたのリストに保持されているオブジェクトではないということです。あなたはBookで、そのタイトルは保持していません。さらに、おそらく(それは大丈夫です)に匹敵するようにBookを実装していないでしょう。

あなたができることは、あなたが最も興味を持っているものによって決まります。ここではすべてのタイトルとそのタイトルのリストにある本の量を保持している例です。

Map<String, Long> duplicatesPerTitle = 
          books.stream() 
           .collect(Collectors.groupingBy(Book::getTitle, 
                   Collectors.counting())); 
System.out.println("duplicatesPerTitle = " + duplicatesPerTitle); 

1より大きい数にのみ関心?ここからは、次のものを使用することもできます:

duplicatesPerTitle.entrySet().stream() 
          .filter(e -> e.getValue() > 1) 
          .forEach(System.out::println); 
関連する問題