第2章 ストリーム API の使い方 : 問題 12, 13 : 並列ストリーム
問題 12
短い単語の数をカウントする処理
Stream<String> words = ~; int[] shortWords = new int[12]; words.parallel() .forEach(s -> { if (s.length() < 12) shortWords[s.length()]++; });
は、競合が起こり正しくカウントできない。
shortWords
をAtomicInteger
の配列に変えて、正しくカウントできるようにせよ
解答
AtomicInteger[] shortWords = new AtomicInteger[12]; Arrays.setAll(shortWords, n -> new AtomicInteger(0)); words.parallel() .forEach(s -> { if (s.length() < 12) shortWords[s.length()].getAndIncrement(); }); // カウント結果の表示 System.out.println(Arrays.toString(shortWords));
問題 13
上の解答で、次の点を変更せよ
- 短い文字列はフィルターで取り出す
Collectors.groupingBy
,Collectors.counting
,collect
メソッドを使用
解答
この場合、AtomicInteger
を使う必要はない。
そして配列ではなくMap<Integer, Long>
に収集する。
Map<Integer, Long> wordsMap = words.parallel() .filter(s -> s.length() < 12) .collect(Collectors.groupingBy(String::length, Collectors.counting())); // カウント結果の表示 for (int n = 0; n < 12; n++) { System.out.print(wordsMap.get(n)); System.out.print(", "); }