0
点赞
收藏
分享

微信扫一扫

如何用Function接口替代复杂的if...else...


在开发过程中经常会使用​​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")
});
}

传值为空的时候则执行另一个


举报

相关推荐

0 条评论