Java优雅判空——Optional

文章介绍了Java中的Optional类,展示了其初始化方法以及如何通过ifPresent、orElse、orElseGet处理可能存在的空值。重点讲解了filter、map和flatMap方法在处理数据和避免空指针异常中的应用,以及与StreamAPI的结合使用。
摘要由CSDN通过智能技术生成

初始化

Optional提供了三个初始化方法:

@SpringBootTest
public class OptionalTest {

    @Test
    public void testOptional() {
	    Optional.empty();
        Optional.ofNullable(null);
        Optional.of(null);
    }
}

empty返回一个空的Optional对象。
of遇到空会报错,但是使用Optional的目的就是防止空指针,所以一般使用ofNullable较多。
在这里插入图片描述

ifPresent

ifPresent——如果存在则xxx

public void testOptional() {
        Student student = new Student();
        student.setName("feng");
        student.setAge(18);
        Optional.of(student);

        // 普通做法
        if(student !=  null){
            System.out.println(student.getName());
        }
        
        // Optional普通用法
        Optional<Student> optional = Optional.ofNullable(student);
        if(optional.isPresent()){
            Student student1 = optional.get();
            System.out.println(student1.getName());
        }

        // 正确用法
        optional.map(new Function<Student, String>() {
            @Override
            public String apply(Student student) {
                return student.getName();
            }
        }).ifPresent(System.out::println);

		// 简化
		optional.map(Student::getName).ifPresent(System.out::println);
    }

orElse和orElseGet

如果没有对象,则调用一个创建对象的方法。
orElse类似于饿汉式,如果当前对象不为空就使用当前的对象,如果为空则调用方法去创建一个新对象。
orElseGet类似于懒汉式,只有当前对象为空才会去调用,通常使用orElseGet较多。

当前对象不为空:

    public void testOptional() {
        Student student = new Student();
        student.setName("feng");
        student.setAge(18);
        Optional<Student> optional = Optional.ofNullable(student);
        Student student1 = optional.orElse(createStudent());
        // orElseGet接收一个Suppilier,一个匿名内部类,调用get方法处理逻辑
        Student student2 = optional.orElseGet(new Supplier<Student>() {
            @Override
            public Student get() {
                return createStudent();
            }
        });
    }

    private Student createStudent(){
        System.out.println("create student");
        return new Student();
    }

在这里插入图片描述

当前对象为空:

    public void testOptional() {
        Student student = null;
        Optional<Student> optional = Optional.ofNullable(student);
        Student student1 = optional.orElse(createStudent());
        // orElseGet接收一个Suppilier,一个匿名内部类,调用get方法处理逻辑
        Student student2 = optional.orElseGet(new Supplier<Student>() {
            @Override
            public Student get() {
                return createStudent();
            }
        });
    }

    private Student createStudent(){
        System.out.println("create student");
        return new Student();
    }

在这里插入图片描述

过滤

	public void testOptional() {
        Student student = new Student();
        student.setName("feng");
        student.setAge(18);
        Optional<Student> optional = Optional.ofNullable(student);
        optional.filter(student1 -> student1.getAge() > 1).ifPresent(student1 -> System.out.println(student1.getAge()));
    }

map和flatMap

Optional是Java中用于处理可能包含或不包含值的容器类。Optional提供了一些方法来对这些值进行操作,其中包括mapflatMap

  1. Optional.map
    • map方法用于在Optional包含值的情况下,对其进行转换或操作。
    • 如果Optional包含一个值,map会将这个值传递给提供的函数,并返回一个包含转换结果的新Optional
    • 如果Optional为空,map不执行任何操作,直接返回一个空Optional
    • map的签名如下:<U> Optional<U> map(Function<? super T, ? extends U> mapper)
Optional<String> optional = Optional.of("Hello");
Optional<Integer> lengthOptional = optional.map(s -> s.length());

在上面的例子中,optional包含一个字符串值"Hello",map方法将字符串长度计算并返回一个新的Optional包含计算结果,即一个整数。

  1. Optional.flatMap
    • flatMap方法用于在Optional包含值的情况下,进行一种扁平映射,它期望传入的函数返回另一个Optional
    • 如果Optional包含一个值,flatMap会将这个值传递给提供的函数,该函数返回一个Optional,然后flatMap返回这个新的Optional
    • 如果Optional为空,flatMap不执行任何操作,直接返回一个空Optional
    • flatMap的签名如下:<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
Optional<String> optional = Optional.of("Hello");
Optional<Integer> lengthOptional = optional.flatMap(s -> Optional.of(s.length()));

在上面的例子中,optional包含一个字符串值"Hello",flatMap方法将字符串长度计算并返回一个新的Optional包含计算结果,即一个整数。注意,flatMap函数返回的是Optional<Integer>,而不是Optional<Optional<Integer>>,这是因为flatMap会自动将嵌套的Optional展平为单层。

总结:

  • map用于对包含的值进行转换,并返回新的Optional
  • flatMap用于对包含的值进行扁平映射,并返回一个新的Optional,通常用于解决嵌套Optional的问题。

整体使用

// 普通
public void before8(List<Student> Students) {
    for (Student student:Students) {
        if (student != null){
            if (student.getAge() > 18){
                Integer score = student.getScore();
                if (score != null && score > 80){
                    System.out.println(student.getName());
                }
            }
        }
    }
}



//1 
public void after8(List<Student> students) {
   students.stream()
           .filter(Objects::nonNull) // 过滤掉空的学生对象
           .filter(student -> student.getAge() > 18) // 按年龄过滤
           .map(Student::getScore) // 映射为分数
           .filter(score -> score != null && score > 80) // 按分数过滤
           .map(Student::getName) // 映射为姓名
           .ifPresent(System.out::println); // 如果存在姓名则打印
}

	public void after8(List<Student> Students) {
        for (Student student:Students) {
            Optional<Student> studentOptional = Optional.of(student);
			
// 2
         Integer sorce = studentOptional
                 .filter(s -> s.getAge() > 18)
                 .map(Student::getScore)
                 .orElse(0);//.orElse(0)返回一个默认值,防止控空指针  
         if (sorce > 80){
             System.out.println(student.getName());
         }


// 3
         String name = studentOptional
                 .filter(s -> s.getAge() >= 18)
                 .filter(s -> s.getScore() > 80)
                 .map(Student::getName)
                 .orElse("wu");//.orElse(0)返回一个默认值,防止控空指针
         System.out.println(name);
     }
    }

Optional类是Java 8中引入的一个用于处理可能为的对象的类。它提供了一种优雅的方式来断对象是否为,并且可以避免使用丑陋的指针检查代码。\[3\] 在引用\[1\]和引用\[2\]的代码示例中,通过将需要的对象转换为Optional对象,我们可以使用Optional类的方法来进行操作。例如,使用map方法可以获取对象的某个属性,然后使用filter方法进行条件过滤,最后使用ifPresent方法来执行某个操作。如果对象为或者不满足条件,这些操作都不会执行。\[1\]\[2\] 通过使用Optional类,我们可以更加清晰和简洁地断对象是否为,避免了繁琐的指针检查。这种写法使代码更加可读性和可维护性。\[3\] #### 引用[.reference_title] - *1* *2* [使用Optional进行操作](https://blog.csdn.net/zx123456_6838499/article/details/129912331)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Java如何进行优雅——Optional类的灵活应用](https://blog.csdn.net/qq_42102911/article/details/129025220)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我顶得了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值