Javaの関数型インターフェース

一、関数型インターフェース

1、概要

関数型インターフェースは、抽象メソッドを一つだけ持つインターフェースです。@FunctionalInterfaceアノテーションを使用することで、インターフェースが関数型インターフェースであることを明示できます。
package com.example.functional;

@FunctionalInterface
public interface MessagePrinter {
    void print();
}
package com.example.functional;

public class Main {
    public static void main(String[] args) {
        MessagePrinter printer = () -> System.out.println("関数型インターフェースのデモ");
        printer.print();
    }
}

2、関数型インターフェースをメソッドのパラメータとして使用

メソッドの引数として関数型インターフェースを受け取ることで、より柔軟なコードを書くことができます。
package com.example.parameter;

public class ThreadDemo {
    public static void main(String[] args) {
        // 匿名クラスを使用する場合
        executeTask(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "が実行中です");
            }
        });
        
        // ラムダ式を使用する場合
        executeTask(() -> System.out.println(Thread.currentThread().getName() + "が実行中です"));
    }
    
    private static void executeTask(Runnable task) {
        new Thread(task).start();
    }
}

3、関数型インターフェースをメソッドの戻り値として使用

メソッドの戻り値として関数型インターフェースを返すことで、動的に比較ロジックを生成できます。
package com.example.returnvalue;

import java.util.Arrays;
import java.util.Comparator;

public class SortDemo {
    public static void main(String[] args) {
        String[] names = {"田中", "鈴木", "佐藤", "山田"};
        System.out.println("ソート前: " + Arrays.toString(names));
        
        Comparator<String> comparator = getStringComparator();
        Arrays.sort(names, comparator);
        
        System.out.println("ソート後: " + Arrays.toString(names));
    }
    
    private static Comparator<String> getStringComparator() {
        return (s1, s2) -> s1.length() - s2.length();
    }
}

二、標準ライブラリで提供される関数型インターフェース

1、Supplier<T> インターフェース

Supplierは値を供給する役割を果たします。パラメータを持たず、指定された型のオブジェクトを返します。
package com.example.supplier;

import java.util.Random;

public class SupplierDemo {
    public static void main(String[] args) {
        int[] numbers = {45, 12, 89, 23, 56};
        int maxValue = findMaximum(() -> {
            int max = numbers[0];
            for (int i = 1; i < numbers.length; i++) {
                if (numbers[i] > max) {
                    max = numbers[i];
                }
            }
            return max;
        });
        System.out.println("最大値: " + maxValue);
    }
    
    private static int findMaximum(java.util.Supplier<Integer> supplier) {
        return supplier.get();
    }
}

2、Consumer<T> インターフェース

Consumerは値を消費する役割を果たします。引数を受け取り、処理を実行しますが、値を返しません。
package com.example.consumer;

public class ConsumerDemo {
    public static void main(String[] args) {
        String[] data = {"田中,28", "佐藤,35", "鈴木,42"};
        processData(data, 
            s -> System.out.print("名前: " + s.split(",")[0] + " / "),
            s -> System.out.println("年齢: " + s.split(",")[1])
        );
    }
    
    private static void processData(String[] array, Consumer<String> first, Consumer<String> second) {
        for (String item : array) {
            first.andThen(second).accept(item);
        }
    }
}

3、Predicate<T> インターフェース

Predicateは条件を評価する役割を果たします。入力された値に対して真偽値を返します。
package com.example.predicate;

import java.util.ArrayList;
import java.util.function.Predicate;

public class PredicateDemo {
    public static void main(String[] args) {
        String[] persons = {"田中太郎,40", "佐藤花子,25", "鈴木一郎,35"};
        ArrayList<String> results = filterPersons(persons, 
            s -> s.split(",")[0].length() >= 4,
            s -> Integer.parseInt(s.split(",")[1]) >= 30
        );
        
        for (String person : results) {
            System.out.println(person);
        }
    }
    
    private static ArrayList<String> filterPersons(String[] data, Predicate<String> condition1, Predicate<String> condition2) {
        ArrayList<String> filtered = new ArrayList<>();
        for (String item : data) {
            if (condition1.and(condition2).test(item)) {
                filtered.add(item);
            }
        }
        return filtered;
    }
}

4、Function<T,R> インターフェース

Functionは入力を受け取り、指定された型の出力を返す変換処理を定義します。
package com.example.function;

import java.util.function.Function;

public class FunctionDemo {
    public static void main(String[] args) {
        String input = "田中,30";
        transformData(input,
            s -> s.split(",")[0],
            Integer::parseInt,
            i -> String.valueOf(i + 10)
        );
    }
    
    private static void transformData(String text, Function<String, String> extractor, 
                                       Function<String, Integer> converter, 
                                       Function<Integer, String> transformer) {
        String result = extractor.andThen(converter).andThen(transformer).apply(text);
        System.out.println("計算結果: " + result);
    }
}

タグ: Java functional-interface lambda supplier consumer

5月31日 17:26 投稿