使用Lambda表达式的前提是有函数式接口,而Lambda表达式使用时不关心接口名,抽象方法名。只关心抽象方法的参数列表和返回值类型,因此为了更加方便的使用Lambda表达式,JDK提供了大量常用的函数式接口(java.util.function包下)。其实JDK提高函数式接口就是为了方便开发者,无需开发者再去定义函数式接口了,下面介绍四种常用的函数式接口。
Supplier函数式接口
@FunctionalInterfacepublic interface Supplier<T> {/*** Gets a result.** @return a result*/T get();}
通过源码可知,Suppler函数式接口没有参数,只有返回值,用于生成数据,比如:
public class LambdaTest {public static void main(String[] args) {fun1(()->{int[] arr={10,22,78,3,56,43,29,75};Arrays.sort(arr);return arr[arr.length-1];});}private static void fun1(Supplier<Integer> supplier){Integer max = supplier.get();System.err.println("max = "+max);}}
Consumer函数式接口
@FunctionalInterfacepublic interface Consumer<T> {/*** Performs this operation on the given argument.** @param t the input argument*/void accept(T t);default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}}
通过源码可知,该函数式接口有参无返回值,用于消费数据,比如:
public class LambdaTest {public static void main(String[] args) {fun2(msg -> {System.err.println(msg + " ---转换为大写--- " + msg.toUpperCase());});}private static void fun2(Consumer<String> consumer) {consumer.accept("consumer accept");}}

此外,该函数式接口还多了一个默认方法andThen,通过源码不难知道它是先执行Consumer t,再执行Consumer after,如:
public class LambdaTest {public static void main(String[] args) {fun3(msg -> {System.err.println(msg + " ---转换为大写--- " + msg.toUpperCase());}, msg2 -> {System.err.println(msg2 + " ---转换成小写--- " + msg2.toLowerCase());});}private static void fun3(Consumer<String> c1, Consumer<String> c2) {String str = "consumer accept";//c1先执行,执行完毕再执行c2c1.andThen(c2).accept(str);}}
Function函数式接口
@FunctionalInterfacepublic interface Function<T, R> {/*** Applies this function to the given argument.** @param t the function argument* @return the function result*/R apply(T t);default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {Objects.requireNonNull(before);return (V v) -> apply(before.apply(v));}default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t));}static <T> Function<T, T> identity() {return t -> t;}}
通过源码可知Function函数式接口有参有返回值,根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。比如:
public class LambdaTest {
public static void main(String[] args) {
fun4(msg -> {
return Integer.parseInt(msg);
});
}
private static void fun4(Function<String, Integer> function) {
System.err.println(function.apply("123345"));
}
}
Predicate函数式接口
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
可以看到,Predicate函数式接口输入数据,返回的是布尔值,其它静态方法和默认方法就是做的“&&”、“||”、“==”等操作,比如:
public class LambdaTest {
public static void main(String[] args) {
fun5(msg -> {
return msg.length() > 20;
});
}
private static void fun5(Predicate<String> p) {
String str = "Hello World";
boolean test = p.test(str);
System.out.println(test);
}
}


