源码地址master
首先看一段代码
publicclassTest{publicstaticvoidmain(String[] args){newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println("老写法");}});newThread(()->{System.out.println("函数式接口新写法");});}}
为什么可以这么写?
publicclassTest{publicstaticvoidmain(String[] args){newThread(()->{System.out.println("songxianyang");});}}
答: 函数式接口
先说一个注解
@FunctionalInterface
用的信息注释类型,以指示在接口类型声明旨在是一个功能接口由Java语言规范所定义的。 在概念上,功能界面只有一个抽象方法。如果接口声明了一个抽象方法覆盖的公共方法之一
java.lang.Object
,也不会向接口的抽象方法计数统计以来的接口的任何实施都会有一个实现从java.lang.Object
或其他地方。请注意,可以使用lambda表达式,方法引用或构造函数引用创建函数接口的实例。
如果使用此注释类型注释类型,则编译器需要生成错误消息,除非:
- 类型是接口类型,而不是注释类型,枚举或类。
- 注释类型满足功能界面的要求。
有哪些函数式接口
new Runnable();无参无返回型函数,没有参数也没有返回值
new Function(); 供给型函数,有参有返回型函数。
new Consumer(); 消费型函数,一个参数,没有返回值
new Supplier(); 供给型函数,有参有返回型函数。
底层源码
Runnable
@FunctionalInterfacepublicinterfaceRunnable{/**
* 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()
*/publicabstractvoidrun();}
Function
@FunctionalInterfacepublicinterfaceFunction<T,R>{/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/Rapply(T t);/**
* Returns a composed function that first applies the {@code before}
* function to its input, and then applies this function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of input to the {@code before} function, and to the
* composed function
* @param before the function to apply before this function is applied
* @return a composed function that first applies the {@code before}
* function and then applies this function
* @throws NullPointerException if before is null
*
* @see #andThen(Function)
*/default<V>Function<V,R>compose(Function<?superV,?extendsT> before){Objects.requireNonNull(before);return(V v)->apply(before.apply(v));}/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@code after} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of output of the {@code after} function, and of the
* composed function
* @param after the function to apply after this function is applied
* @return a composed function that first applies this function and then
* applies the {@code after} function
* @throws NullPointerException if after is null
*
* @see #compose(Function)
*/default<V>Function<T,V>andThen(Function<?superR,?extendsV> after){Objects.requireNonNull(after);return(T t)-> after.apply(apply(t));}/**
* Returns a function that always returns its input argument.
*
* @param <T> the type of the input and output objects to the function
* @return a function that always returns its input argument
*/static<T>Function<T,T>identity(){return t-> t;}}
Consumer
@FunctionalInterfacepublicinterfaceConsumer<T>{/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/voidaccept(T t);/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/defaultConsumer<T>andThen(Consumer<?superT> after){Objects.requireNonNull(after);return(T t)->{accept(t); after.accept(t);};}}
Supplier
@FunctionalInterfacepublicinterfaceSupplier<T>{/**
* Gets a result.
*
* @return a result
*/Tget();}
代码实现
- 需求:简化if…else{} 可以采用
代码结构
MyUtils
packagecom.example.demo.myfunction.impl;importcom.example.demo.myfunction.ExceptionFunction;importcom.example.demo.myfunction.FunctionIfEOrElse;/**
* 功能描述:
*
* @author Songxianyang
* @date 2022-04-27 18:10
*/publicfinalclassMyUtils{/**
* if else 加工
* @param b
* @return
*/publicstaticFunctionIfEOrElseisTrue(Boolean b){return(runnableTrue, runnableFalse)->{if(b){
runnableTrue.run();}else{
runnableFalse.run();}};}/**
* 打印消息 测试
* @return
*/publicstaticExceptionFunctionisMsg(){return msg1->{System.out.println(msg1);};}}
ExceptionFunction
/**
* 功能描述:异常信息输出
*
* @author Songxianyang
* @date 2022-04-27 18:26
*/@FunctionalInterfacepublicinterfaceExceptionFunction{/**
* 异常信息输出
* @param msg
*/voidthrowOut(String msg);}
FunctionIfEOrElse
/**
* 功能描述:执行对应的分支
*
* @author Songxianyang
* @date 2022-04-27 17:42
*/@FunctionalInterfacepublicinterfaceFunctionIfEOrElse{/**
* 执行对应的分支
* @param runnableTrue
* @param runnableFalse
*/voidprint(Runnable runnableTrue,Runnable runnableFalse);}
测试类
/**
* 功能描述:
*
* @author Songxianyang
* @date 2022-04-27 18:10
*/publicclassPrintTest{publicstaticvoidmain(String[] args){MyUtils.isTrue(true).print(()->{System.out.println("执行true业务代码");},()->{System.out.println("执行FALSE业务代码");});RuntimeException exception=newRuntimeException("我报错了 请指示");MyUtils.isMsg().throwOut(exception.getMessage());}
总结
- Function函数可以大大的简化代码。看着就是优雅好懂