函数式接口指的是有且只有一个抽象方法的接口。

JDK提供的默认的函数式接口


可以根据使用场景,是否需要返回值,返回值类型,入参数量等,选择合适的函数式接口。

 

例子:

Consumer接口

只有一个入参,没有返回值

Consumer consumer = s -> System.out.println(s); // 一个入参,无返回值

consumer.accept(“hello”);

等价于:

Consumer consumer = (s) -> {System.out.println(s);}

或Consumer consumer = (s) -> {System.out::println;}

Supplier接口

没有入参,只有一个返回值

Supplier<String> supplier = () -> "i am supplier";
log.info(supplier.get());

 

Function接口

根据一个类型的数据得到另一个类型的数据

java.util.function.Function<T,R> 接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件.

比如想要进行属性之间的转换,如String->Integer,就可以使用Function接口。Function的泛型一般有两种类型,前面的类型T表示传入的参数类型,后面的类型R表示返回值类型

例子:

Function<Integer, String> function = s -> s + "123";
System.out.println(function.apply(100));

 

Function函数接口的特点经常被用于Stream流操作过程中,作为map方法的入参。

String str1 = "Hello My World.";
Stream.of(str1.split(" "))

.filter(s -> s.length() > 2)

.map(s -> s.length())

.forEach(System.out::println);

相当于:

Function<String, Integer> function = s -> s.length();

Stream.of(str1.split(" "))

.filter(s -> s.length() > 2)

.map(function)

.forEach(System.out::println);

 

Predicate接口

表示一个参数的谓词(布尔值函数)。这个接口包含一个抽象方法 test(T t),用于对输入参数进行评估,并返回一个布尔值。



Predicate<String> isEmpty = String::isEmpty;
System.out.println(isEmpty.test("")); // 输出 true


List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
Predicate<String> startsWithA = name -> name.startsWith("A");
List<String> filteredNames = names.stream()
.filter(startsWithA)
.collect(Collectors.toList());


Predicate 接口还提供了几个默认方法来创建复合谓词,如 andor 和 negate

Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isGreaterThanFive = n -> n > 5;

Predicate<Integer> isEvenAndGreaterThanFive = isEven.and(isGreaterThanFive);
Predicate<Integer> isEvenOrGreaterThanFive = isEven.or(isGreaterThanFive);
Predicate<Integer> isNotEven = isEven.negate();

System.out.println(isEvenAndGreaterThanFive.test(6)); // 输出 true
System.out.println(isEvenOrGreaterThanFive.test(3)); // 输出 true
System.out.println(isNotEven.test(4)); // 输出 false


注意:以上这些是通用的函数式接口,使用的是泛型。

还有很多专用的函数式接口,比如Runnable。可以根据使用场景选择。

 

Runnable接口

Runnable接口包含一个无参数、无返回值的方法run()。它通常用于表示一个可以在新线程中执行的任务。

Runnable task = () -> System.out.println("Task is running in a new thread");
new Thread(task).start();


Callable<V>接口

Runnable类似,但Callable允许任务有返回值,并且可以抛出异常。它包含一个call()方法,该方法可以返回结果或抛出异常。

Callable<String> callableTask = () -> "Result of callable task";
Future<String> future = Executors.newSingleThreadExecutor().submit(callableTask);
try {
System.out.println(future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}


Comparator<T>接口

Comparator接口用于定义对象比较的方法。它包含一个compare(T o1, T o2)方法,该方法用于比较两个对象。

Comparator<Integer> comparator = (a, b) -> Integer.compare(a, b);
int result = comparator.compare(5, 3);
System.out.println(result > 0 ? "a is greater" : "a is not greater");



方法引用

更简洁的写法:

Consumer consumer = System.out::println;

consumer.accept(“hello”);

如果函数式接口的实现恰好可以通过调用一个方法来实现,那么我们可以使用方法引用。

 

方法引用又分了几种:

静态方法的方法引用,类名::静态方法名;

非静态方法的方法引用,实例名::非静态方法名;

构造函数的方法引用,类名::new;

 

最近学到的Lambda表达式基础知识_3y-CSDN博客

 

Supplier supplier = () -> “hello”; // 无入参,有返回值

String str = supplier.get();

 

Supplier supplier = MyClass::new; // 把Lambda表达式简化为方法调用

String str = supplier.get();

这些默认的函数式接口的使用场景是什么?

java8 Consumer supplier predicate function 简单使用示例_zhaozhen的博客-CSDN博客