Java8 -- Optional 使用

179 阅读2分钟

Optional 创建

import com.lwl.javaBasic.model.TestModel;
import com.lwl.javaBasic.model.TestModel2;
import java.util.ArrayList;
import java.util.Optional;

/**
 * @Author LWL
 * @Date 2022/7/31 15:07
 * @TODO Optional
 */
public class create {

    public static void main(String[] args) {
        Optional<TestModel> opModel = setModel();
        opTest1(opModel);
        opApi1(opModel);
        opApi2(opModel);
        opApi3(opModel);
    }    

Optional 常用Api

    /*
     * of 和 ofNullable 区别在于
     * of 如果数据没处理好,传入一个Null值则会抛空指针
     * ofNullable可传入一个 Null值且系统不会抛异常
     *
     * =============================  ofNullable 源码  ====================================
     *
     * public static <T> Optional<T> ofNullable(T value) {
     *   return value == null ? empty() : of(value);
     * }
     * 由此可见ofNullable可以接收为空数据是因为底层已经对其传入数据进行一个判空处理
     * 如果传入为空,则返回一个空的 Optional对象 否则调用 of 方法对其进行一个处理
     *
     * get() 不推荐使用 因为get方法在某些时候会导致空指针异常
     *
     */
     
      public static Optional<TestModel> setModel() {
        TestModel model = new TestModel();
        ArrayList<TestModel2> list = new ArrayList<>();
        list.add(new TestModel2().setHeight(170).setHobby("A - hobby"));
        model.setAge(10)
                .setName("A")
                .setSex("男")
                .setTestModel2(list);
        return Optional.ofNullable(model);
    }

isPresent & ifPresent

  public static void opTest1(Optional<TestModel> opModel) {
      try {
          opModel.ifPresent(item -> System.out.println(item.getName()));
          if (opModel.isPresent()) {
              Integer age = opModel.get().getAge();
          }
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

orElseGet & orElseThrow

//  orElseGet   orElseGet 可以理解为设置默认值
//  orElseThrow (如果有值则返回对应值,否则抛出自定义异常)
public static void opApi1(Optional<TestModel> opModel) {
    try {
        opModel.orElseGet(() -> new TestModel());
        opModel.orElseThrow(() -> new RuntimeException("必要参数为Null >>> {}")); //
    } catch (Exception e) {
        e.printStackTrace();
    }
}

filter

     //  filter (符合过滤条件的则返回,如果没有符合的,则返回一个空的Optional对象)
    public static void opApi2(Optional<TestModel> opModel) {
        try {
            System.out.println(opModel.filter(item -> item.getAge() > 9));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Map

 // map 数据转换 (mapToInt  mapToLong mapToDouble 可减少不必要的装箱拆箱操作)
public static void opApi3(Optional<TestModel> opModel) {
    try {
        opModel.map(item -> item.getTestModel2())
                .ifPresent(item2 -> System.out.println(item2));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

应用场景

1.     if (patientInfo != null) consultInfoResp.setPatientHead(patientInfo.getHead());

- > Optional 写法 
       Optional.ofNullable(patientInfo)
       .ifPresent(pconsultInfoResp.setPatientHead(p.getHead()));
2.     Student student = new Student(null, 3);
       if (student == null || isEmpty(student.getName())) throw new Exception();
       String name = student.getName();
       
- > Optional 写法 
       Optional.ofNullable(student)
       .filter(s -> !isEmpty(s.getName())).orElseThrow(() -> new Exception());
3.     if (comp != null) {
       CompResult result = comp.getResult();
       if (result != null)  User champion = result.getChampion();
       if (champion != null) return champion.getName();
       }
       throw new IllegalArgumentException("message ....");
       
- > Optional 写法 
       return Optional.ofNullable(comp)
             .map(Competition::getResult)
             .map(CompResult::getChampion)
             .map(User::getName)
             .orElseThrow(()->new IllegalArgumentException("message...."));
       }
       
4.   if (ObjectUtil.isNotNull(testModel)) {
      if (StrUtil.isNotEmpty(testModel.getName()) && StrUtil.isNotEmpty(testModel.getSex())) {
        System.out.println("业务逻辑");
      }
     } else {
         throw new RuntimeException();
     }
     
- > Optional 写法 
Optional.ofNullable(testModel)
        .filter(((Predicate<TestModel>) testModel1 -> StrUtil.isNotEmpty(testModel1.getName()))
                .and(testModel13 -> StrUtil.isNotEmpty(testModel13.getSex()))
                .or(testModel12 -> CollectionUtil.isNotEmpty(testModel12.getTestModel2()))
                .negate()); // 把上述条件取反 == !(非)

函数式接口 (只有一个抽象方法的接口)

一般使用 @FunctionalInterface声明

所在路径 java.util.function

常用函数式接口
-   Function  —  函数型接口  -> (有输入、有返回)
-   Predicate —  断定型接口  -> (有输入,返回boolean)
-   Consumer  —  消费型接口  -> (只有输入,无返回)
-   Supplier  —  供给型接口  -> (无入参,只有返回值)