在开发过程中经常会使用if...else...
进行判断抛出异常、分支处理等操作。这些if...else...
充斥在代码中严重影响了代码代码的美观,这时我们可以利用Java的Function接口来消灭if...else...
if (...){
throw new RuntimeException("出现异常了");
}
if (...){
doSomething();
} else {
doOther();
}
Function 函数式接口
使用注解@FunctionalInterface
标识,并且只包含一个抽象方法的接口是函数式接口。函数式接口主要分为Supplier
供给型函数、Consumer
消费型函数、Runnable
无参无返回型函数和Function
有参有返回型函数
Function可以看作转换型函数
Supplier供给型函数
Supplier
的表现形式为不接受参数、只返回数据,他代表结果的提供者
@FunctionalInterface
public interface Supplier<T>{
// Get a result
T get();
}
Consumer消费型函数
Consumer
消费型函数和Supplier
刚好相反。Consumer
接收一个参数,没有返回值
@FunctionalInterface
public interface Consumer<T>{
// 对给定参数执行此操作
void accept(T t);
//返回一个组合的Consumer,依次执行此操作和after操作,如果执行任一操作引发异常,则将其转发给组合操作的调用者,如果执行此操作抛出异常,则不会执行after操作
@Contract(pure = true) @NotNull
default Consumer<T> andThen(@NotNull Consumer<? super T> after){
Objects.requireNonNull(after);
return(T t) -> {accept(t); after.accept(t);};
}
}
Runnable无参无返回型函数
Runnable
的表现形式为即没有参数也没有返回值
Runnable接口应该由线程执行的任何类实现,该类必须定义一个名为run的无参数方法,此接口为希望在活动时执行代码的对象提供通用协议,例如Runnable是由类Thread实现的,处于活动状态仅意味着线程已启动且尚未停止
Runnable提供了使类处于活动状态而不是子类化Thread,通过实例化Thread实例并将自身作为目标传入,实现Runnable的类可以不再集成Thread的情况下运行,在大多数情况下,如果只打算覆盖run()方法而不打算覆盖其他的Thread方法,则应该使用Runnable接口,实际上若非程序员打算修改或增强类的基本行为,否则类不应该被子类化
Thread, java.util.concurrent.Callable
Thread.run()
@FunctionalInterface
public interface Runnable{
//当使用实现接口Runnable的对象创建线程时,启动线程会导致在单独执行的线程中调用对象的run方法,而方法run一般约定是它可以采取任何行动
public abstract void run();
}
Function
函数的表现形式为接收一个参数,并返回一个值。Supplier
、Consumer
和Runnable
可以看作Function
的一种特殊表现形式
@FunctionalInterface
public interface Function<T, R>{
R apply(T t);
//返回一个组合函数,该函数首先将before函数应用于其输出,然后将此函数应用于结果,如果对任一函数的,如果对任一函数的评估引发异常,则将其转发给组合函数的调用者,before:在应用此函数之前要应用的函数,参数类型: <V> -before函数和组合函数的输入类型,返回值:首先应用before函数然后应用此函数的组合函数,可参考andThen(Function)
@Contract(pure = true) @NotNull
default <V> Function<V, R> compose(@NotNull Function<? super V, ? extends T> before){
Objects,requireNonNull(before);
return(V v) -> apply(before.apply(V));
}
}
处理抛出异常的if
定义函数,定义一个抛出异常的函数式接口,这个接口只有参数没有返回值是个消费型接口
/**
* 抛出异常接口
**/
@FunctionalInterface
public interface ThrowExceptionFunction{
void throwMessage(String message);
}
编写判断方法,创建工具类Utils
并创建一个isTure
方法,方法的返回值为刚才定义的函数式接口ThrowExceptionFunction
, ThrowExceptionFunction
的接口实现逻辑为当参数b为true时抛出异常
//如果参数为true则抛出异常 @return com.example.demo.func.ThrowExceptionFunction
public static ThrowExceptionFunction isTure(boolean b){
return(errorMessage) ->{
if(b){
throw new RuntimeException(errorMessage);
}
};
}
使用方式,调用工具类参数后,调用函数式接口的throwMessage方法传入异常信息,当输入的参数为false时正常执行
@Test
void isTrue(){
Utils.isTure(b:false).throwMessage("试试抛出异常啦")
}
@Test
void isTrue(){
Util.isTrue(b:true).throwMessage("参数为true,要抛出异常了")
}
处理if分支操作
创建一个名为BranchHandle的函数式接口,接口的参数为两个Runnable接口,这两个Runnable接口分别代表了为true或false时要进行的操作
//分支处理接口
@FunctionalInterface
public interface BranchHandle{
void trueOrFalseHandle(Runnable trueHandle, Runnable falseHandle);
}
编写一个判断方法,方法的返回值为刚才定义的BranchHandle
//@return com.example.demo.func.BranchHandle
public static BranchHandle isTrueOrFalse(boolean b){
return(trueHandle, falseHandle)->{
if(b){
trueHandle.run();
} else{
falseHandle.run();
}
}
}
参数为true
时,执行trueHandle
@Test
void isTureOrFalse(){
Utils.isTureOrFalse(b:true)
.trueOrFalseHandle(trueHandle:()->){
System.out.println("true, Lets go");
}, falseHandle:()->{
System.out.println("false, Lets run");
});
}
参数为false的时候则执行另一个
如果存在值则执行消费操作,否则执行基于空的操作
创建一个名为PresentOrElseHandler的函数式接口,接口参数为Consumer接口,一个名为Runnable
,分别代表值不为空时执行消费操作和值为空时执行的其他操作
//空值和非空值处理
public interface PresentOrElseHandle<T extends Object>{
void presentOrElseHandle(Consumer<? super T> action, Runnable emptyAction);
}
创建一个名为isBlankOrNoBlank
的方法, 方法的返回值为刚才定义的PresentOrElseHandler
public static PresentOrElseHandler<?> isBlankOrNoBlank(String str){
return (consumer, runnable) ->{
if(str == null || str.length() == 0)
runnable.run();
}else{
consumer.accept(str);
}
};
}
@Test
void isBlankOrNoBlank(){
Utils.isBlankOrNoBlank(str:"davieyang")
.presentOrElseHandle(System.out::println, () ->{
System.out.println("null string")
});
}
传值为空的时候则执行另一个