13. Optional -常用方法

60 阅读2分钟

13. Optional -

image.png

Optional类主要是解决空指针的问题

1. 以前对null的处理

@Test
@DisplayName("以前对于空指针的处理")
public void test1() {
    String userName = null;
    if(userName != null) {
        System.out.println("字符串的长度:" + userName.length());
    }

    if(userName == null) {
        System.out.println("字符串为空");
    }
}
字符串为空

Optional类

Optional是一个没有子类的工具类,Optional是一个可以为null的容器对象,它的主要作用就是为了避免Null检查,防止NPE。

Optional中的值有两种

  • 有值
  • null

image.png

Optional的基本使用

Optional.of() 方法不支持null

@Test
@DisplayName("Optional.of() 方法不支持null")
public void test2() {
    Optional<String> result = Optional.of("zhangsan");
    System.out.println("result = " + result);

    Optional<Object> result2 = Optional.of(null);
    System.out.println("result2 = " + result2);
    
}
result = Optional[zhangsan]


java.lang.NullPointerException

Optional.ofNullable() 方法支持null

@Test
@DisplayName("Optional.ofNullable() 方法支持null")
public void test3() {

    Optional<String> result3 = Optional.ofNullable("lisi");
    System.out.println("result3 = " + result3);

    Optional<String> result4 = Optional.ofNullable(null);
    System.out.println("result4 = " + result4);

}
result3 = Optional[lisi]
result4 = Optional.empty

通过Optional方法直接创建一个空的Optional对象

@Test
@DisplayName("通过Optional方法直接创建一个空的Optional对象")
public void test4() {

    Optional<Object> empty = Optional.empty();
    System.out.println("empty = " + empty);

}

Optional 常用方法

1. 获取Optional.of中的值

@Test
@DisplayName("获取Optional.of中的值")
public void test5() {

    Optional<String> op1 = Optional.of("zhansgan");


    // 获取Optional中的值
    String s1 = op1.get();
    System.out.println("s1 = " + s1);
}
s1 = zhansgan

2. 获取Optional.empty()中的值

通过Optional.empty() 方法获取值是失败的【调用get方法】

get()方法的作用:如果Optional有值则返回,否则抛出异常java.util.NoSuchElementException

image.png

@Test
@DisplayName("获取Optional.empty()中的值")
public void test6() {

    Optional<Object> op1 = Optional.empty();
    System.out.println("op1 = " + op1.get());

}

报错

java.util.NoSuchElementException: No value present

3. isParsent()

get() 方法通常和isParsent方法一块使用。

isParsent()方法的作用是判断是否有值,有则返回true,无则返回false

image.png

@Test
@DisplayName("isParsent()")
public void test7() {
    Optional<Object> op1 = Optional.empty();
    Optional<String> op2 = Optional.of("zhangsan");

    if(op1.isPresent()) {
        System.out.println("op1 = " + op1.get());
    }else {
        System.out.println("op1是一个空的Optional对象");
    }

    if (op2.isPresent()) {
        System.out.println("op2 = " + op2.get());
    }

}
op1是一个空的Optional对象
op2 = zhangsan

4. orElse()

orElse()会判断是不是空值,如果是null值,则返回orElse()中的值。

如果调用的对象有值,就返回对象的值。

@Test
@DisplayName("orElse()")
public void test8() {
    Optional<String> op1 = Optional.empty();
    Optional<String> op2 = Optional.of("zhangsan");


    String name1 = op1.orElse("lisi");
    String name2 = op2.orElse("wangwu");


    System.out.println("name1 = " + name1);
    System.out.println("name2 = " + name2);
}
name1 = lisi
name2 = zhangsan

5. orElseGet()

orElseGet() 会判断对象里是否有值,如果是null则,返lambda表达式中的值。

@Test
@DisplayName("orElseGet()")
public void test9() {
    Optional<String> op1 = Optional.empty();
    String s = op1.orElseGet(() -> {
        return "hello";
    });
    System.out.println("s = " + s);
}

Optional 高级方法

ifPresent()

@Test
@DisplayName("ifPresent()")
public void test10() {
    Optional<String> op1 = Optional.empty();
    Optional<String> op2 = Optional.of("zhangsan");

    // 如果存在值,就做什么
    op2.ifPresent(s -> System.out.println("有值:" + s));
    // 如果存在值,就做什么【方法引用版】
    op2.ifPresent(System.out::println);
    
}
有值:zhangsan
zhangsan

/**
 * 自定义一个方法,将Person对象中的name转换为大写并返回
 */
@Test
@DisplayName("ifPresent()")
public void test11() {
    PersonDO p = new PersonDO("zhangsan", 18, 188);
    Optional<PersonDO> op = Optional.of(p);
    String name = getNameForOptional(op);
    System.out.println("name = " + name);

}

/**
 * 根据PersonDO对象 将name转换为大写并返回
 * @param personDO
 * @return
 */
public String getName(PersonDO personDO) {

    String name = personDO.getName();
    if (personDO != null){
        if (personDO!= null) {
            return name.toUpperCase();
        }else {
            return null;
        }
    }else {
        return null;
    }
}

/**
 * 根据PersonDO对象 将name转换为大写并返回
 *  通过Optional方式现实
 * @param op
 * @return
 */
public String getNameForOptional(Optional<PersonDO> op){
    String s = null;
    if (op.isPresent()){
        s = op.map(p -> p.getName())
                .map(p -> p.toUpperCase())
                .orElse("空值");
    }

    return s;
}
name = ZHANGSAN