学会Optional妈妈再也不用担心我的代码空指针了!!!优雅永不过时

为了更深入展示 Optional 的 API,这次我们会涉及更多的 Optional 方法,比如 map()flatMap()orElse()orElseGet()orElseThrow()。我们继续使用之前的 Useremail 场景,并引入更多的处理方式。

示例场景扩展:

在这次的示例中,我们会进一步扩展场景,比如:

  • User 对象与 Address 对象结合,演示 Optional 嵌套和 flatMap() 的使用。
  • 展示各种 Optional 的 API,比如默认值、异常抛出等情况。
使用 Optional 之前的代码:
public class Address {
    private String street;

    public Address(String street) {
        this.street = street;
    }

    public String getStreet() {
        return street;
    }
}

public class User {
    private String email;
    private Address address;

    public User(String email, Address address) {
        this.email = email;
        this.address = address;
    }

    public String getEmail() {
        return email;
    }

    public Address getAddress() {
        return address;
    }
}

public class Main {
    public static void main(String[] args) {
        Address address = new Address("123 Main St");
        User userWithEmailAndAddress = new User("user@example.com", address);
        User userWithoutEmail = new User(null, null);

        printUserEmail(userWithEmailAndAddress);
        printUserEmail(userWithoutEmail);

        printUserAddress(userWithEmailAndAddress);
        printUserAddress(userWithoutEmail);
    }

    public static void printUserEmail(User user) {
        if (user != null && user.getEmail() != null) {
            System.out.println("User's email is: " + user.getEmail());
        } else {
            System.out.println("User's email is not available.");
        }
    }

    public static void printUserAddress(User user) {
        if (user != null && user.getAddress() != null) {
            System.out.println("User's address is: " + user.getAddress().getStreet());
        } else {
            System.out.println("User's address is not available.");
        }
    }
}
使用 Optional 之后的代码:

我们使用 Optional 包装 emailaddress,并展示各种 Optional 的方法。

import java.util.Optional;

public class Address {
    private String street;

    public Address(String street) {
        this.street = street;
    }

    public String getStreet() {
        return street;
    }
}

public class User {
    private Optional<String> email;
    private Optional<Address> address;

    public User(String email, Address address) {
        // 使用 Optional 包装 email 和 address
        this.email = Optional.ofNullable(email);
        this.address = Optional.ofNullable(address);
    }

    public Optional<String> getEmail() {
        return email;
    }

    public Optional<Address> getAddress() {
        return address;
    }
}

public class Main {
    public static void main(String[] args) {
        Address address = new Address("123 Main St");
        User userWithEmailAndAddress = new User("user@example.com", address);
        User userWithoutEmail = new User(null, null);

        // 演示 Optional 的各种方法
        printUserEmail(userWithEmailAndAddress);
        printUserEmail(userWithoutEmail);

        printUserAddress(userWithEmailAndAddress);
        printUserAddress(userWithoutEmail);

        // 进一步展示 Optional 的其他操作
        demonstrateOptionalAPIs(userWithEmailAndAddress);
        demonstrateOptionalAPIs(userWithoutEmail);
    }

    public static void printUserEmail(User user) {
        // 使用 ifPresentOrElse 打印 email 或缺省值
        user.getEmail().ifPresentOrElse(
            email -> System.out.println("User's email is: " + email),
            () -> System.out.println("User's email is not available.")
        );
    }

    public static void printUserAddress(User user) {
        // 使用 flatMap 处理嵌套的 Optional
        String street = user.getAddress()
                            .flatMap(Address::getStreet) // 展开嵌套的 Optional
                            .orElse("Address is not available.");
        System.out.println("User's address: " + street);
    }

    public static void demonstrateOptionalAPIs(User user) {
        // 使用 map 操作 email 并将其转为大写
        String upperCaseEmail = user.getEmail()
                                    .map(String::toUpperCase)  // 转换为大写
                                    .orElse("DEFAULT@EMAIL.COM");
        System.out.println("Uppercase email: " + upperCaseEmail);

        // 使用 orElse 提供默认值
        String email = user.getEmail().orElse("default@example.com");
        System.out.println("Email: " + email);

        // 使用 orElseGet 提供通过 Lambda 计算的默认值
        String emailWithSupplier = user.getEmail().orElseGet(() -> "supplier@example.com");
        System.out.println("Email with supplier: " + emailWithSupplier);

        // 使用 orElseThrow 在没有值时抛出异常
        try {
            String mustHaveEmail = user.getEmail().orElseThrow(() -> new IllegalArgumentException("Email is required!"));
            System.out.println("Email: " + mustHaveEmail);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

详细讲解 Optional API 的变化:

  1. ifPresentOrElse()

    • 之前:我们需要手动进行 null 检查。
    • 之后:使用 Optional.ifPresentOrElse(),可以简化逻辑,并直接在 Optional 存在值或不存在值时执行不同的操作。
  2. map()

    • 之前:我们需要对获取的值进行检查,然后手动转换。
    • 之后:通过 Optional.map(),我们可以在值存在时对其进行转换操作,而无需显式检查 null
  3. flatMap()

    • 之前:嵌套的 Optional 需要层层检查。
    • 之后:使用 flatMap(),可以避免嵌套 Optional,直接对内部值进行操作。
  4. orElse()

    • 之前:手动为 null 值提供默认值。
    • 之后Optional.orElse() 允许我们提供默认值,如果值为 null,则返回默认值。
  5. orElseGet()

    • 区别:与 orElse() 类似,但 orElseGet() 接收一个 Supplier(函数式接口),当值不存在时,Supplier 会被执行来生成默认值,这在需要计算默认值的情况下更加高效。
  6. orElseThrow()

    • 之前:如果值不存在,需要手动抛出异常。
    • 之后:使用 Optional.orElseThrow(),我们可以在值为 null 时自动抛出指定的异常。

总结:

使用 Optional 后,代码不但更加简洁,还能通过函数式编程的方式进行操作,减少显式的 null 检查。此外,Optional 提供了丰富的 API,可以处理不同的情况,如提供默认值、抛出异常、转换值等。通过这些 API 的合理使用,能够显著提高代码的健壮性和可读性。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值