简单示例:java
interface MyFunctionInterfaceOne<T>{ void saySomething(T t); }
上面就符合成为函数式接口的条件,即接口里面只有一个抽象方法,若是咱们在接口中再加上一个抽象方法:web
interface MyFunctionInterfaceOne<T>{ void saySomething(T t); void saySomething2(T t); }
这个时候该接口就不是一个函数式接口了,已经变成一个普通的接口,固然,此时也不会报错。可是,若是给该接口加上注解@FunctionalInterface,变成:编程
@FunctionalInterface interface MyFunctionInterfaceOne<T>{ void saySomething(T t); }
那么此时,在该接口下就不能再增长抽象方法,不然编译时就会出错。
固然,除了只能有一种抽象方法外,函数式接口内还能够有其余三种类型的方法:dom
示例以下:ide
@FunctionalInterface interface MyFunctionInterfaceTwo<T>{ void saySomething(T t); /** * 函数式接口里是能够包含默认方法,由于默认方法不是抽象方法,其有一个默认实现,因此是符合函数式接口的定义的; */ default void sayHello(){ System.out.println("hello"); } /** * 函数式接口里是能够包含静态方法,由于静态方法不能是抽象方法,是一个已经实现了的方法,因此是符合函数式接口的定义的; */ static void sayGoodbye(){ System.out.println("goodbye"); } /** * 函数式接口里是能够包含Object里的public方法,这些方法对于函数式接口来讲,不被当成是抽象方法(虽然它们是抽象方法); * 由于任何一个函数式接口的实现,默认都继承了Object类,包含了来自java.lang.Object里对这些抽象方法的实现; * @param anObject * @return */ @Override boolean equals(Object anObject); }
@Slf4j public class FunctionalInterfaceDemo { @Test public void test1(){ //lambda表达式不能是泛型的,可是与lambda表达式关联的函数式接口能够是泛型的 MyFunctionInterfaceOne<String> a = x -> log.info(x); MyFunctionInterfaceTwo<String> b = x -> System.out.println(x); //将函数式接口做为形参传入方法 FunctionalInterfaceDemo.arraySay(b, Arrays.asList("zao","mian","bao")); } public static <T> void arraySay(MyFunctionInterfaceTwo<T> operation , List<T> list ){ if (list instanceof RandomAccess){ for (int i = 0; i < list.size(); i++) { operation.saySomething(list.get(i)); } }else { Iterator<T> iterator = list.iterator(); for (int i = 0; i < list.size(); i++) { T next = iterator.next(); operation.saySomething(next); } } } }
在上面的示例中,咱们将函数式接口做为形参传入arraySay方法,而后在arraySay这样调用了函数式接口中的方法:svg
operation.saySomething(list.get(i));
而后就会出现这样的状况,在咱们没有传入函数式接口参数的参数值时,该方法具体如何执行咱们是不知道的,只有当咱们使用了Lambda表达式编写了实现的动做或者说具体的操做后,咱们才知道arraySay最终会作些什么,因此函数式接口的出现给了方法极大的拓展空间,使代码之间弱耦合,同时实现了将一个动做做为参数传入到方法中,为Java的函数式编程作出了巨大的贡献。函数式接口、Lambda表达式、方法引用、Steam流一块儿实现了Java的函数式编程。函数式编程
这里只列出平时常常使用和接触到的接口函数
接口 | 做用 |
---|---|
Runnable | 声明一个线程的具体实现没有返回值,配合Thread使用 |
Comparator | 声明一个比较方式,通常配合集合排序使用 |
InvocationHandler | 声明一个代理对象方法的额外具体实现,配合Proxy一块儿使用 |
Callable | 声明一个线程的具体实现且有返回值,配合Future或FutureTask使用 |
新增的函数式接口都在java.util.function包下ui
接口 | 定义 |
---|---|
Consumer | 消费型接口,接受参数,无返回值类型的接口 |
Function | 函数型接口,输入参数,输出结果 |
Supplier | 供给类型得接口,只有返回值,没有入参 |
Predicate | 断言型接口,输入参数,输出boolean类型的返回值 |
Consumerthis
接口 | 定义 |
---|---|
Consumer | 表明了接受一个输入参数而且无返回的操做 |
BiConsumer<T,U> | 表明了一个接受两个输入参数的操做,而且不返回任何结果 |
DoubleConsumer | 表明一个接受double值参数的操做,而且不返回结果 |
IntConsumer | 接受一个int类型的输入参数,无返回值 |
LongConsumer | 接受一个long类型的输入参数,无返回值 |
ObjDoubleConsumer | 接受一个object类型和一个double类型的输入参数,无返回值 |
ObjIntConsumer | 接受一个object类型和一个int类型的输入参数,无返回值 |
ObjLongConsumer | 接受一个object类型和一个long类型的输入参数,无返回值 |
Function
接口 | 定义 |
---|---|
Function<T,R> | 接受一个输入参数,返回一个结果 |
BiFunction<T,U,R> | 表明了一个接受两个输入参数的方法,而且返回一个结果 |
DoubleFunction | 表明接受一个double值参数的方法,而且返回结果 |
DoubleToIntFunction | 接受一个double类型输入,返回一个int类型结果 |
DoubleToLongFunction | 接受一个double类型输入,返回一个long类型结果 |
IntFunction | 接受一个int类型输入参数,返回一个结果 |
IntToDoubleFunction | 接受一个int类型输入,返回一个double类型结果 |
IntToLongFunction | 接受一个int类型输入,返回一个long类型结果 |
LongFunction | 接受一个long类型输入参数,返回一个结果 |
LongToDoubleFunction | 接受一个long类型输入,返回一个double类型结果 |
LongToIntFunction | 接受一个long类型输入,返回一个int类型结果 |
ToDoubleBiFunction<T,U> | 接受两个输入参数,返回一个double类型结果 |
ToDoubleFunction | 接受一个输入参数,返回一个double类型结果 |
ToIntBiFunction<T,U> | 接受两个输入参数,返回一个int类型结果 |
ToIntFunction | 接受一个输入参数,返回一个int类型结果 |
ToLongBiFunction<T,U> | 接受两个输入参数,返回一个long类型结果 |
ToLongFunction | 接受一个输入参数,返回一个long类型结果 |
BinaryOperator | 表明了一个做用于于两个同类型操做符的操做,而且返回了操做符同类型的结果 |
DoubleBinaryOperator | 表明了做用于两个double值操做符的操做,而且返回了一个double值的结果 |
DoubleUnaryOperator | 接受一个参数同为类型double,返回值类型也为double |
IntBinaryOperator | 接受两个参数同为类型int,返回值类型也为int |
IntUnaryOperator | 接受一个参数同为类型int,返回值类型也为int |
LongBinaryOperator | 接受两个参数同为类型long,返回值类型也为long |
LongUnaryOperator | 接受一个参数同为类型long,返回值类型也为long |
UnaryOperator | 接受一个参数为类型T,返回值类型也为T |
这里Operator结尾的接口都继承了Function接口,都是属于有输入,有返回值的函数式接口类型
Supplier
接口 | 定义 |
---|---|
Supplier | 无参数,返回一个结果 |
BooleanSupplier | 表明了boolean值结果的提供方 |
DoubleSupplier | 表明一个double值结构的提供方 |
IntSupplier | 无参数,返回一个int类型结果 |
LongSupplier | 无参数,返回一个结果long类型的值 |
Predicate
接口 | 定义 |
---|---|
Predicate | 接受一个输入参数,返回一个布尔值结果 |
BiPredicate<T,U> | 表明了一个两个参数的boolean值方法 |
DoublePredicate | 表明一个拥有double值参数的boolean值方法 |
IntPredicate | 接受一个int输入参数,返回一个布尔值的结果 |
LongPredicate | 接受一个long输入参数,返回一个布尔值类型结果 |
Iterable中的forEach方法
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
Collections中的sort方法
public static <T> void sort(List<T> list, Comparator<? super T> c) { list.sort(c); }
NativeLibLoader中的静态代码块
static { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { verbose = Boolean.getBoolean("javafx.verbose"); return null; }); }