質問の解釈
質問の意図を『関数をメソッドの引数にとるにはどうすればよいか』と解釈します。バージョンは、Java 8とします。
【第1案】 Function<T,U>、 Consumer<T>
まずmapを作る関数(Function)を定義します。関数の型は、List<String> -> Map<String, Long>
Java
1Function<List<String>,Map<String, Long>> supplyMap = x -> x.stream().collect(groupingBy(identity(), counting()));
質問の動作を実行させる、カウントした度数を表示する消費者(Consumer)をつくります。内部でsupplyMap.apply(x)を呼びます。関数の型は、List<String> -> void?
Java
1Consumer<List<String>> showFreqs = x -> supplyMap.apply(x).values().stream().filter(e -> e > 1).forEach(System.out::println);
メソッドの引数
消費者をメソッドの引数として渡して評価します。
Java
1static void evaluateConsumer(Consumer<List<String>> f) {
2 List<String> values = Arrays.asList("HND", "NRT", "KIX", "NGO", "NGO", "NGO", "NGO", "NGO");
3 f.accept(values);
4}
【第2案】 Supplier<T>、 Runnable
キャプチャを使って供給者(Supplier)にすると以下のようになります。関数の型は、() -> Map<String, Long>
Java
1List<String> values = Arrays.asList("HND", "NRT", "KIX", "NGO", "NGO", "NGO", "NGO", "NGO");
2Supplier<Map<String, Long>> supplier = () -> values.stream().collect(groupingBy(identity(), counting()));
引数を取らず値も返さない関数。内部で上で定義したsupplier.get()を呼びます。
Java
1Runnable showFreqs2 = () -> supplier.get().entrySet().stream().filter(e -> e.getValue()>1).forEach(System.out::println);
Runnableをメソッドの引数として渡して評価します。
Java
1static void evaluateRunnable(Runnable f) {
2 f.run();
3}
質問の意図を取り違えていたらごめんなさい。
追記します
【ファイナルアンサー?】 peek()
これでよいでしょうか。曲芸です。何の意味もありません。
- デバッグ用のpeek()を使って1以上の度数を表示
- peek()を使うために、MapをEntrySetにばらして、再びMapに組立て直す
(filter()などを使って新しいMapを作るのなら、EntrySetにばらす意味があります ... )
Java
1Function<List<String>,Map<String, Long>> function =
2 x -> x.stream().collect(groupingBy(identity(), counting()))
3 .entrySet().stream()
4 .peek(e -> {if (e.getValue() > 1) System.out.println(e.getValue());})
5 .collect(toMap(Entry::getKey, Entry::getValue));
6
7List<String> values = Arrays.asList("HND", "NRT", "KIX", "NGO", "NGO", "NGO", "NGO", "NGO");
8
9Map<String, Long> result = function.apply(values);
10System.out.println(result);
11
【ファイナルアンサー?】が正しいなら前の回答はとりさげます。関数インターフェイスのバリエーションを示しただけ。