一、関数型インターフェース
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);
}
}