运用Function接口,简洁的判断并抛出异常



运用Function接口,简洁的判断并抛出异常

学习资料地址:妙用Java 8中的 Function接口 消灭if...else(非常新颖的写法

书读百遍,其义自现

纸上得来终觉浅,绝知此事要躬行

基础

Function函数式接口

使用注解@FunctionalInterface标识,并且只包含一个抽象方法的接口是函数式接口函数式接口主要分为Supplier供给型函数、Consumer消费型函数、Runnable无参无返回型函数和Function有参有返回型函数。

Function可以看作转换型函数

Supplier供给型函数

Supplier的表现形式为不接受参数、只返回数据

package java.util.function;
?
/**
* Represents a supplier of results.
*
*

There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
*
*

This is a functional interface
* whose functional method is {@link #get()}.
*
* @param the type of results supplied by this supplier
*
* @since 1.8
*/
@FunctionalInterface
public interface Supplier<T> {
?
   /**
    * Gets a result.
    *
    * @return a result
    */
   T get();
}

 

Consumer消费型函数

Consumer消费型函数和Supplier刚好相反。Consumer接收一个参数,没有返回值

@FunctionalInterface
public interface Consumer<T> {
?
   /**
    * Performs this operation on the given argument.
    *
    * @param t the input argument
    */
   void accept(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
    */
   default Consumer<T> andThen(Consumer<? super T> after) {
       Objects.requireNonNull(after);
       return (T t) -> { accept(t); after.accept(t); };
  }
}

 

Runnable无参无返回型函数

Runnable的表现形式为即没有参数也没有返回值

@FunctionalInterface
public interface Runnable {
   /**
    * When an object implementing interface Runnable is used
    * to create a thread, starting the thread causes the object's
    * run method to be called in that separately executing
    * thread.
    *


    * The general contract of the method run is that it may
    * take any action whatsoever.
    *
    * @see     java.lang.Thread#run()
    */
   public abstract void run();
}

 

Function函数的表现形式为接收一个参数,并返回一个值。SupplierConsumerRunnable可以看作Function的一种特殊表现形式

 

运用

01 处理抛出异常的if(常用)

1 定义函数

定义一个抛出异常的形式的函数式接口, 这个接口只有参数没有返回值是个消费型接口

/**
* 抛出异常的接口
* @author : lyn
* @date : 2022-05-07 21:56
*/
@FunctionalInterface
public interface ThrowExceptionFunction {
?
   /**
    * 抛出异常
    * @param errorMessage 异常信息
    */
   void throwException(String errorMessage);
}

 

2 编写判断方法

创建工具类ConciseUtil并创建一个isTure方法,方法的返回值为刚才定义的函数式接口-ThrowExceptionFunctionThrowExceptionFunction的接口实现逻辑为当参数flagtrue时抛出异常

/**
* 简洁的工具类
* 简化代码
*
* @author : lyn
* @date : 2022-05-07 21:53
*/
public class ConciseUtil {
?
   public static ThrowExceptionFunction isTrue(boolean flag) {
       return (errorMessage -> {
           if (flag) {
               throw new RuntimeException(errorMessage);
          }
?
      });
?
  }
}

3 使用方式

调用工具类参数参数后,调用函数式接口throwException方法传入异常信息。当出入的参数为false时正常执行

/**
* @author : lyn
* @date : 2022-05-07 22:01
*/
public class TestMain {
   public static void main(String[] args) {
       ConciseUtil.isTrue(true).throwException("不能为空");
  }
}

 

02 处理if分支操作(便于理解源码)

1 定义函数式接口

创建一个名为BranchHandle的函数式接口,接口的参数为两个Runnable接口。这两个两个Runnable接口分别代表了为truefalse时要进行的操作

/**
* 分支处理接口
* @author : lyn
* @date : 2022-05-07 22:35
*/
public interface BranchHandle {
?
   /**
    * 分支操作
    * @param trueHandle true时执行
    * @param falseHandle false时执行
    */
   void trueOrFalseHandle(Runnable trueHandle,Runnable falseHandle);
}

 

2 编写判断方法

创建一个名为isTureOrFalse的方法,方法的返回值为刚才定义的函数式接口-BranchHandle

    /**
    * 参数为true或false时,分别进行不同的操作
    * @param flag
    * @return
    */
   public static BranchHandle isTrueOrFalse(boolean flag) {
       return ((trueHandle, falseHandle) -> {
           if (flag){
               trueHandle.run();
          }else{
               falseHandle.run();
          }
      });
?
  }

3 使用方式

参数为true时,执行trueHandle

ConciseUtil.isTrueOrFalse(false).trueOrFalseHandle(
              ()->{
                   System.out.println("执行true操作");
              },
              ()->{System.out.println("执行false操作");});

 

03 如果存在值执行消费操作,否则执行基于空的操作

1 定义函数

创建一个名为PresentOrElseHandler的函数式接口,接口的参数一个为Consumer接口。一个为Runnable,分别代表值不为空时执行消费操作和值为空时执行的其他操作

/**
* 空值与非空值分支处理
* @author lyn
*/
public interface PresentOrElseHandler<T extends Object> {
?
   /**
    * 值不为空时执行消费操作
    * 值为空时执行其他的操作
    *
    * @param action 值不为空时,执行的消费操作
    * @param emptyAction 值为空时,执行的操作
    * @return void    
    **/
  void presentOrElseHandle(Consumer<? super T> action, Runnable emptyAction);
 
}

 

1 编写判断方法

创建一个名为isBlankOrNoBlank的方法,方法的返回值为刚才定义的函数式接口-PresentOrElseHandler

/**
* 空值与非空值分支处理
* @author lyn
*/
public interface PresentOrElseHandler<T extends Object> {
?
   /**
    * 值不为空时执行消费操作
    * 值为空时执行其他的操作
    *
    * @param action 值不为空时,执行的消费操作
    * @param emptyAction 值为空时,执行的操作
    * @return void    
    **/
  void presentOrElseHandle(Consumer<? super T> action, Runnable emptyAction);
 
}

 

2 编写判断方法

创建一个名为isBlankOrNoBlank的方法,方法的返回值为刚才定义的函数式接口-PresentOrElseHandler

  /**
    * 参数为空或不为空时,分别进行不同的操作
    *
    * @param str
    * @return
    **/
   public static PresentOrElseHandler<?> isBlankOrNoBlank(String str) {
?
       return (consumer, runnable) -> {
           if (str == null || str.length() == 0) {
               runnable.run();
          } else {
               consumer.accept(str);
          }
      };
  }

 

3 使用方式

调用工具类参数参数后,调用函数式接口presentOrElseHandle方法传入一个ConsumerRunnable

参数不为空时,打印参数

 ConciseUtil.isBlankOrNoBlank("welcome to beijing").presentOrElseHandle(
               System.out::print,
              () -> {
                   System.out.println("空字符串");
              });

 

存在问题

Consumer<? super T> action

待学习