TFdream / blog

个人技术博客,博文写在 Issues 里。
Apache License 2.0
129 stars 18 forks source link

Java 8 Optional使用 #428

Open TFdream opened 2 years ago

TFdream commented 2 years ago

Guide To Java 8 Optional : https://www.baeldung.com/java-optional

示例类:

public class Person {
    private String name;
    private String gender;
    private int age;
    private Location location;

}

public class Location {
    private String country;
    private String city;

}

2.1 map + orElse

功能描述:判断Person在哪个城市,并返回城市小写名;失败时返回nowhere。

传统写法1:

public static String inWhichCityLowercaseTU(Person person) { //Traditional&Ugly
    if (person != null) {
        Location location = person.getLocation();
        if (location != null) {
            String city = location.getCity();
            if (city != null) {
                return city.toLowerCase();
            } else {
                return "nowhere";
            }
        } else {
            return "nowhere";
        }
    } else {
        return "nowhere";
    }
}

可见,层层嵌套,繁琐且易错。

传统写法2:

public static String inWhichCityLowercaseT(Person person) { //Traditional
    if (person != null
            && person.getLocation() != null
            && person.getLocation().getCity() != null) {
        return person.getLocation().getCity().toLowerCase();
    }
    return "nowhere";
}

这种写法优于前者,但级联判空很容易"淹没"正常逻辑(return句)。

新式写法:

public static String inWhichCityLowercase(final Person person) {
    return Optional.ofNullable(person)
        .map(Person::getLocation)
        .map(Location::getCity)
        .map(String::toLowerCase)
        .orElse("nowhere");
}

采用Optional的写法,逻辑层次一目了然。似无判空,胜却判空,尽在不言中。

2.2 map + orElseThrow

功能描述:判断Person在哪个国家,并返回国家大写名;失败时抛出异常。

新式写法如下:

public static String inWhichCountryUppercase(final Person person) {
    return Optional.ofNullable(person)
        .map(Person::getLocation)
        .map(Location::getCountry)
        .map(String::toUpperCase)
        .orElseThrow(NoSuchElementException::new);
    // 或orElseThrow(() -> new NoSuchElementException("No country information"))
}

2.3 map + orElseGet

功能描述:判断Person在哪个国家,并返回from + 国家名;失败时返回from Nowhere。

新式写法:

private String fromCountry(final String country) {
    return "from " + country;
}
private String fromNowhere() {
    return "from Nowhere";
}
private String fromWhere(final Person person) {
    return Optional.ofNullable(person)
            .map(Person::getLocation)
            .map(Location::getCountry)
            .map(this::fromCountry)
            .orElseGet(this::fromNowhere);
}