Lambda表达式用来实现SAM接口的,SAM(Single Abstract Method)接口中只有一个抽象方法需要实现,当然该接口可以包含其他非抽象的方法。满足“SAM“特征的接口都可以称为函数式接口(就是用来简化编程模型的),但是如果要更明确一点,最好在声明接口时,在上面加上**@FunctionalInterface**
JDK8之前核心类库中就已经存在很多SAM接口了:
java.lang.Iterablejava.io.FileFilterjava.lang.Runnablejava.util.concurrent.Callablejava.util.Comparatorjava.lang.reflect.InvocationHandler但是在JDK8中只有后三种加了@FunctionalInterface,那些没有加注解的SAM接口现在可以使用Lambda表达式,但是存在将来增加抽象方法变成非SAM接口的风险,所以建议只对加了@FunctionalInterface的接口使用Lambda表达式实现。
JDK8中,在java.util.function包中增加了很多函数式接口,不过他们可以归纳为四类:消费型接口、供给型接口、功能型接口、断言型接口。一共43个。基本上是可以满足开发中函数式接口的基本使用需求。
注意下面列出的每种类型的接口,第一个接口通常是是我们最常用的接口。都用第一个来举例子:
8个。特点:有参无返回值
接口名抽象方法描述Consumervoid accept(T t)接收一个对象用于完成功能BiConsumer<T,U>void accept(T t,U u)接收一个对象用于完成功能DoubleConsumervoid accept(double value)接收一个double值IntConsumervoid accept(int value)接收一个int值LongConsumervoid accept(long value)接收一个long值ObjDoubleConsumervoid accept(T t,double value)接收一个对象和一个double值ObjIntConsumervoid accept(T t,int value)接收一个对象和一个int值ObjLongConsumervoid accept(T t,long value)接收一个对象和一个long值 //Consumer消费型接口,传入一个值,方法体中可以随意定义怎么消费 Consumer<String> consumer = (x)-> System.out.println(x.toUpperCase()); consumer.accept("hello");5个。特点:无参有返回值
接口名抽象方法描述SupplierT get()返回一个T类型结果BooleanSupplierboolean getAsBoolean()返回一个boolean类型结果DoubleSupplierdouble getAsDouble()返回一个double类型结果IntSupplierint getAsInt()返回一个int类型结果LongSupplierlong getAsLong()返回一个long类型结果 //Supplier供给型接口,返回一个任意类型的对象 Supplier<Double> supplier = ()-> Math.random();//返回一个随机的0~1之间的小数 System.out.println(supplier.get());5个。特点:有参返回boolean类型的结果
接口名抽象方法描述Predicateboolean test(T t)接收一个对象BiPredicate<T,U>boolean test(T t,U u)接收两个对象DoublePredicateboolean test(double value)接收一个double值IntPredicateboolean test(int value)接收一个int值LongPredicateboolean test(long value)接收一个long值 //Predicate断言型接口,返回值一定是true或false Predicate<Integer> predicate = (n)-> { return n % 2 == 0; };//判断传入的整数是否为偶数 int n = 100; System.out.println(n+"是否为偶数:"+predicate.test(n));25个。特点:既有参数也有返回值
接口名抽象方法描述Function<T,R>R apply(T t)接收一个T类型对象,返回一个R类型对象UnaryOperatorR apply(T t)接收一个T类型对象,返回一个T类型对象DoubleFunctionR apply(double value)接收一个double值,返回一个R类型对象IntFunctionR apply(int value)接收一个int值,返回一个R类型对象LongFunctionR apply(long value)接收一个long值,返回一个R类型对象ToDoubleFunctiondouble applyAsDouble(T value)接收一个类型对象,返回一个double值ToIntFunctionint applyAsInt(T value)接收一个类型对象,返回一个int值ToLongFunctionlong applyAsLong(T value)接收一个类型对象,返回一个long值DoubleToIntFunctionint applyAsInt(double value)接收一个double值,返回一个int结果DoubleToLongFunctionlong applyAsInt(double value)接收一个double值,返回一个long值IntToDoubleFunctiondouble applyAsInt(int value)接收一个int值,返回一个double值IntToLongFunctionlong applyAsInt(int value)接收一个int值,返回一个long值LongToDoubleFunctiondouble applyAsInt(long value)接收一个long值,返回一个double值LongToIntFunctionint applyAsInt(long value)接收一个long值,返回一个int值DoubleUnaryOperatordouble applyAsDouble(double operand)接收一个double,返回一个doubleIntUnaryOperatorint applyAsInt(int operand)接收一个int,返回一个intLongUnaryOperatorlong applyAsLong(long operand)接收一个long,返回一个longBiFunction<T,U,R>R apply(T t,U u)接收一个T类型和一个U类型的对象,返回一个R类型的结果BinaryOperatorT apply(T t1,T t2)接收两个T类型的对象,返回一个T类型的结果ToDoubleBiFunction<T,U>double applyAsDouble(T t,U u)接收一个T类型和一个U类型的对象,返回一个doubleToIntBiFunction<T,U>int applyAsInt(T t,U u)接收一个T类型和一个U类型的对象,返回一个intToLongBiFunction<T,U>long applyAsLong(T t,U u)接收一个T类型和一个U类型的对象,返回一个longDoubleBinaryOperatordouble applyAsDouble(double left,double right)接收两个double类型的对象,返回一个doubleIntBinaryOperatorint applyAsInt(int left,int right)接收两个int类型的对象,返回一个intLongBinaryOperatorlong applyAsLong(long left,long right)接收两个long类型的对象,返回一个long //Function功能型接口,传入一个任意类型对象,返回一个任意类型对象 Function<String,Integer> function = (str)->{ int n=0; for (int i=0;i<str.length();i++){ if (Character.isDigit(str.charAt(i))){ n++; } } return n; }; String str = "abc123123123"; System.out.println(str+"中的数字个数为:"+function.apply(str));