(Java8)関数型インターフェースの使用方法
関数型インターフェースの種類
Function
Predicate
Consumer
Supplier
Function
Functionインターフェースは、引数を受け取って処理を行い返却する。 例はCSVを受け取って分割しリストに変換している。
public static void main(String[] args) { Function<String, List<String>> f = (line) -> { String[] array = line.split(","); List<String> returnList = Arrays.asList(array); return returnList; }; List<String> list = f.apply("1,2,3,4,5"); list.forEach(System.out::println); }
結果
1 2 3 4 5
Predicate
Predicateは、引数を受け取って判断し、booleanを返す。 例は文字列が3文字以上かを判断している。
public static void main(String[] args) { Predicate<String> f = s -> s.length() > 3; Arrays.asList("a", "bb", "ccc", "ddd", "eeee", "fffff").stream() .filter(s -> f.test(s)) .forEach(System.out::println); }
結果
eeee fffff
Consumer
Consumerインターフェースは、引数を受け取って消費する。 例は引数を標準出力に表示しているだけ。
public static void main(String[] args) { Consumer<String> f = s -> System.out.println(s); List<String> list = Arrays.asList("a", "b", "c"); list.stream() .forEach(s -> f.accept(s)); }
結果
a b c
Supplier
Supplierインターフェースはある決まったものを返す。
public static void main(String[] args) { Supplier<String> f = () -> "Supplier"; IntStream.rangeClosed(1, 3) .forEach(i -> System.out.println(f.get())); }
結果
Supplier Supplier Supplier
ここまでのサンプルじゃあ恩恵もないし、わざわざ使わなくてもと思うし、関数型インターフェース使わなくてもストリームの中でラムダでいいじゃんというのもある意見だと思うけど、ある程度の量のラムダだと可読性がひどく悪い。
ので、ここで関数型インターフェースを使う。(と、思うんだ。)
ここでは、一番使うであろうFunctionインターフェースを例にしてみる。
Functionインターフェース「f」はCSVのリストをFlatMapして返す。(FlatMapについては前日のエントリを参照)
public static void main(String[] args) { Function<String, List<String>> f = s -> { String[] array = s.split(","); List<String> list = Arrays.asList(array); return list; }; List<String> list = new ArrayList<>(); list.add("1,2,3"); list.add("4,5"); list.add("6,7,8,9"); list.stream() .flatMap(line -> f.apply(line).stream())) .collect(Collectors.toList()) .forEach(System.out::println);; }
結果
1 2 3 4 5 6 7 8 9
関数型インターフェースを使った関数を使ったことによってStream処理のところがとても読みやすくないかい?