10.4 使用Optional的实战示例

10.4.1 用Optional封装可能为null的值

通过Optiona封装方法的返回值,实现潜在为null对象的安全转换

Object value = map.get("key");

// 重构
Optional<Object> value = Optional.ofNullable(map.get("key"));

10.4.2 异常与Optional的对比

在函数无法返回有效值时,除了返回null,还有抛出异常的情形。

通过try-catch捕获函数异常,返回Optional.empty()

public static Optional<Integer> stringToInt(String s) {
    try {
        return Optional.of(Integer.parseInt(s));
    } catch (NumberFormatException e) {
        return Optional.empty();
    }
}

基础类型的Optional对象,以及为什么应该避免使用它们

Optional跟Stream类似,对于Optional,可以用OptionalInt替代

泛型Optional 基础类型Optional 泛型Stream 基础类型Stream
Optional OptionalInt Stream IntStream
Optional OptionalLong Streaml LongStream
Optional OptionalDouble Stream DoubleStream

若Stream对象包含了大量元素,出于性能的考量,使用基础类型,但对Optional对象而言,至多包含一个值,这个理由就不成立了。

基础类型Optional无法跟泛型Optional组合使用,不支持map、flatMap以及filter方法,因此出于便利性,不推荐使用基础类型的Optional。

10.4.3 把所有内容整合起来

展示之前介绍过的Optional类的各种方法整合在一起的效果。

public Properties buildProperties() {
    Properties props = new Properties();
    props.setProperty("a", "5");
    props.setProperty("b", "true");
    props.setProperty("c", "-3");
    return props;
}

public static int readDuration(Properties properties, String name) {
    String value = properties.getProperty(name);
    try {
        int result = Integer.parseInt(value);
        if (result > 0) {
            return result;
        }
    } catch (NumberFormatException ignored) {
    }
    return 0;
}

@Test
public void testReadDuration() {
    Properties param = buildProperties();
    Assert.assertEquals(5, readDuration(param, "a"));
    Assert.assertEquals(0, readDuration(param, "b"));
    Assert.assertEquals(0, readDuration(param, "c"));
    Assert.assertEquals(0, readDuration(param, "d"));
}

测验10.3:使用Optional从属性中读取duration

受前面的测验影响,写得复杂了些

public static int readDuration(Properties properties, String name) {
    return Optional.ofNullable(properties).flatMap(props -> OptionalUtility.stringToInt(props.getProperty(name)))
            .filter(value -> value >= 0).orElse(0);
}

更简洁版

public static int readDuration(Properties properties, String name) {
    return Optional.ofNullable(properties.getProperty(name)).flatMap(OptionalUtility::stringToInt)
            .filter(value -> value >= 0).orElse(0);
}

Optional和Stream时的这些通用模式,都是对数据库查询过程的反思,查询时,多种操作会被串接在一起执行。

  1. 实际在互联网业务开发中,为降低数据库的负载,通用做法是执行简单SQL语句,由后端实现复杂逻辑的运算;

  2. 大数据写离线任务,可以执行复杂的SQL逻辑运算;

posted @ 2023-05-28 14:06  夜是故乡明  阅读(39)  评论(0编辑  收藏  举报