概述
函数式接口(Functional Interface)即只有一个抽象方法的接口。
Runnable接口就是一个函数式接口,Runnable接口中只包含一个抽象的run()方法,并且在接口上标注了一个@FuncationInterface注解,用来标识一个函数式接口
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
定义创建函数式接口
- 定义一个抽象方法:注意,接口中只能有一个抽象方法;
- 在接口上标记@FunctionalInterface 注解,当然也可以不标记,注解的作用主要是编辑器就自动检测定义的函数式接口是否有问题。
创建函数式接口
@FunctionalInterface
public interface FunctionalInterfaceTest {
void foo();
}
测试函数式接口
public class FunctionalInterfaceDemo {
public static void main(String[] args) {
FunctionalInterfaceTest functionalInterfaceTest = new FunctionalInterfaceTest() {
@Override
public void foo() {
System.out.println("hello world");
}
};
functionalInterfaceTest.foo();
// lambda
FunctionalInterfaceTest lambdaTest = ()->System.out.println("hello lambda");
lambdaTest.foo();
}
}
使用Lambda表达式来创建,这种方法相较匿名内部类更加简洁,
内置函数式接口
JDK 8 之后新增了一个函数接口包 java.util.function 这里面包含了我们常用的一些函数接口:
接口 | 参数 | 返回类型 | 说明 |
---|---|---|---|
Predicate | T | boolean | 接受一个输入参数 T,返回一个布尔值结果 |
Supplier | None | T | 无参数,返回一个结果,结果类型为 T |
Consumer | T | void | 代表了接受一个输入参数 T 并且无返回的操作 |
Function |
T | R | 接受一个输入参数 T,返回一个结果 R |
UnaryOperator | T | T | 接受一个参数为类型 T, 返回值类型也为 T |
BinaryOperator | (T,T) | T | 代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果 |
Consumer
Comsumer
public class ConsumerDemo {
public static void main(String[] args) {
Consumer<String> consumer = s->System.out.println(s);
consumer.accept("hello world");
}
}
Supplier
Supplier
// Supplier接口源码
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
java.util.function.Supplier 接口仅包含一个无参的方法: T get() 。用来获取一个泛型参数指定类型的对象数据。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据
public class SupplierDemo {
public static void main(String[] args) {
Supplier<String> supplier = () -> "hello world";
String s = supplier.get();
System.out.println(s);
}
}
Function
Function
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
......
}
apply
Function 接口中最主要的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。 使用的场景例如:将 String 类型转换为 Integer 类型。
public class FunctionApplyDemo {
public static void main(String[] args) {
Function<String, Integer> f = s -> Integer.parseInt(s);
int num = f.apply("2");
// 5
System.out.println(num + 3);
}
}
andThen
andThen 方法用来进行组合操作。JDK源代码如:
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
eg:
public class FunctionAndThenDemo {
public static void main(String[] args) {
method(
str -> Integer.parseInt(str) + 2,
i -> i *= 3
);
}
private static void method(Function<String, Integer> one, Function<Integer, Integer> two) {
int num = one.andThen(two).apply("1");
//(1+2)*3+1
System.out.println(num + 1);
}
}
public class FunctionDemo {
public static void main(String[] args) {
String str = "a-1";
int age = getNum(
str,
s -> s.split("-")[1],
s -> Integer.parseInt(s),
n -> n += 2
);
System.out.println(age);
}
private static int getNum(String str,
Function<String, String> one,
Function<String, Integer> two,
Function<Integer, Integer> three) {
return one.andThen(two).andThen(three).apply(str);
}
}
Predicate
某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用java.util.function.Predicate 接口。
Predicate
test
Predicate 接口中包含一个抽象方法: boolean test(T t) 。用于条件判断的场景:
逻辑关系。
与 (and) 、或 (or) 、非 (negate) 的默认方法