Optional

简介

Optional是一个容器对象,它可能包含某个值,也可能不包含,它的设计目的是为了解决空指针异常问题。
使用Optional可以避免在代码中显式地检查null值。
不过这个类有好有坏,适当使用即可,其缺点就是造成代码过于冗长,最主要是引入额外的对象开销。

常见的Optional用法

现有一个实体类UserVo,该类有两个属性usernamepassword,下述示例以该实体类测试。

创建Optional对象

of()方法

创建一个包含指定非null值的Optional对象

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.of(userVo.getUsername());
        if (usernameOptional.isPresent()) {
            System.err.println("获取的信息为 " + usernameOptional.get());
        } else {
            System.err.println("usernameOptional为空");
        }
    }
}

// 执行结果
获取的信息为 张三

使用of()方法创建了一个包含非null值的Optional对象。然后我们通过调用isPresent()方法检查Optional是否包含值。如果Optional包含值,则调用get()方法获取该值并打印输出;否则打印输出Optional为空。

使用of()方法时,如果传入的值为null,会立即抛出NullPointerException异常。因此,在使用of()方法创建Optional对象时,需要确保传入的值不为空。如果值可能为空,可以使用ofNullable()方法创建Optional对象,该方法可以接受null值。

ofNullable()方法

创建一个包含指定值的Optional对象,如果值为null,则创建一个空的Optional对象。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        UserVo userVo = new UserVo();
        // userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        if (usernameOptional.isPresent()) {
            System.err.println("获取的信息为 " + usernameOptional.get());
        } else {
            System.err.println("usernameOptional为空");
        }
    }
}

// 执行结果
usernameOptional为空

使用ofNullable()方法创建了一个包含指定值的Optional对象。如果值为null,则创建一个空的Optional对象。然后我们通过调用isPresent()方法检查Optional是否包含值。如果Optional包含值,则调用get()方法获取该值并打印输出;否则打印输出Optional为空。

使用ofNullable()方法创建的Optional对象可以接受null值,不会立即抛出NullPointerException异常。这样可以更灵活地处理可能为空的值。

empty()方法

创建一个空的Optional对象。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        Optional<String> usernameOptional = Optional.empty();
        if (usernameOptional.isPresent()) {
            System.err.println("获取的信息为 " + usernameOptional.get());
        } else {
            System.err.println("usernameOptional 为空");
        }
    }
}

// 执行结果
usernameOptional为空

使用empty()方法创建了一个空的Optional对象。然后我们通过调用isPresent()方法检查Optional是否包含值。由于我们使用empty()方法创建的Optional对象是空的,所以isPresent()返回值为false,程序会打印输出Optional为空,使用empty()方法创建的Optional对象始终是空的,不包含任何值,这在某些情况下可以用于表示缺失值。

判断Optional是否包含值

isPresent()方法

如果Optional对象包含值,则返回true,否则返回false,上述示例判断部分已经用到

ifPresent()方法

如果Optional对象不为空则执行ifPresent()中的处理逻辑,否则不予执行。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        usernameOptional.ifPresent(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.err.println("业务逻辑处理");
            }
        });
    }
}

userVo正常给userName赋值时

输出结果:业务逻辑处理

没有赋值时,不输出任何结果

获取Optional中的值

get()方法

如果Optional对象包含值,则返回该值,否则抛出NoSuchElementException异常,上述示例判断部分已经用到

注意,使用get()方法时,一定要先使用isPresent()方法来检查Optional对象是否包含值,以避免抛出异常

filter()方法

用于过滤 Optional 对象中的值,只有当值满足特定条件时才保留

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        Optional<String> optional = usernameOptional.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 2;
            }
        });
        System.err.println(optional.get());
    }
}

上述过滤条件为字符串的长度是否为2,是的话取出值

输出结果:张三

但当长度判断不是等于2时,过滤后没有符合条件的数据,会抛出NoSuchElementException异常。

orElse()方法

如果Optional对象包含值,则返回该值,否则返回指定的默认值。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.of(userVo.getUsername());
        // Optional<String> usernameOptional = Optional.empty();
        String string = usernameOptional.orElse("李四");
        System.err.println(string);
    }
}

使用of()方法创建一个非空的Optional对象,并将赋值后的userName作为值传递给它。然后,我们使用orElse()方法获取Optional对象的值,如果Optional对象为空,则返回指定的默认值"李四"。

当示例中调用的是of()方法时

输出结果:张三

当示例中调用的是empty()方法时

输出结果:李四

orElseGet()方法

如果Optional对象包含值,则返回该值,否则通过调用Supplier接口提供的方法来生成一个默认值。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        UserVo userVo = new UserVo();
        // userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        String string = usernameOptional.orElseGet(new Supplier<String>() {
            @Override
            public String get() {
                return "李四";
            }
        });
        System.out.println(string);
    }
}

使用ofNullable()方法创建了一个包含指定值的Optional对象。如果值为null,则创建一个空的Optional对象。然后调用了orElseGet()方法。

运行测试,当userVo正常给userName赋值时

输出结果:张三

没有赋值时

输出结果:李四

orElseThrow()方法

如果Optional对象包含值,则返回该值,否则通过调用Supplier接口提供的方法来抛出指定的异常。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        // userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        String string = usernameOptional.orElseThrow(new Supplier<Throwable>() {
            @Override
            public Throwable get() {
                throw new RuntimeException("抛出指定异常");
            }
        });
        System.err.println(string);
    }
}

userVo正常给userName赋值时

输出结果:张三

没有赋值时

java 复制代码
Exception in thread "main" java.lang.RuntimeException: 抛出指定异常
	at com.sun.test.OptionalTest$1.get(OptionalTest.java:16)
	at com.sun.test.OptionalTest$1.get(OptionalTest.java:13)
	at java.util.Optional.orElseThrow(Optional.java:290)
	at com.sun.test.OptionalTest.main(OptionalTest.java:13)

转换Optional中的值

map()方法

对Optional中的值进行转换,并返回一个新的Optional对象。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        Optional<String> optional = usernameOptional.map(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s + " -- 值转换";
            }
        });
        System.err.println(optional.get());
    }
}

创建一个包含指定值的Optional对象,如果值为null,则创建一个空的Optional对象,userVo.getUsername()不为空,走后续逻辑,调用map()方法,生成新的Optional对象,最后用get()方法获取Optional中的值。

输出结果:张三 -- 值转换

flatMap()方法

Optional中的值进行转换,并返回一个新的Optional对象。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        Optional<String> optional = usernameOptional.flatMap(new Function<String, Optional<String>>() {
            @Override
            public Optional<String> apply(String s) {
                return Optional.ofNullable(s + " -- 值转换");
            }
        });
        System.err.println(optional.get());
    }
}
输出结果:张三 -- 值转换

输出结果与调用map()一样,且该方法处理逻辑稍复杂一些,map()flatMap()按需选择即可。

相关推荐
向前看-14 分钟前
验证码机制
前端·后端
xlsw_16 分钟前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹1 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭2 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫2 小时前
泛型(2)
java
超爱吃士力架2 小时前
邀请逻辑
java·linux·后端
南宫生2 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石2 小时前
12/21java基础
java
李小白662 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp2 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea