Java8新特性--Optional

本文深入解析Java8中Optional类的功能与用法,包括避免NullPointerException、of与ofNullable方法的区别、ifPresent、orElse、orElseGet、orElseThrow等方法的使用场景,以及map与flatMap的高级应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * Optional:供应商的意思
 * Optional 不是接口而是一个类,这是个用来防止NullPointerException异常的辅助类型
 * Optional 被定义为一个简单的容器,其值可能是null或者不是null
 * 在Java8之前一般某个函数应该返回非空对象但是偶尔却可能返回了null,而在Java 8中,不推荐你返回null而是返回Optional
 * 这是一个可以为null的容器对象
 * 如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象
 *
 */
public class OptionalDemo01 {

    /**
     * requireNonNull(T obj, Supplier<String> messageSupplier), 是否为空,可以自己定义一个Lambda类, Supplier<String>
     *
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("------------of方法----------------");
        /**
         * of方法 为非null的值创建一个Optional类
         * 需要注意的是,创建对象时传入的参数不能为Null
         * 如果传入的参数为null, 那么抛出异常NullPointerException
         */
        Optional<String> op1 = Optional.of("Hello123");
        System.out.println(op1.get());

        /**
         * 传入一个为null的值
         * 抛出异常:java.lang.NullPointerException
         */
        //Optional<String> op2 = Optional.of(null);

        /**
         * 如果加入一个空集合会怎么样
         */
        List<Integer> list = new ArrayList<Integer>();
        /**
         * 不会报任何异常
         */
        Optional<List<Integer>> opList1 = Optional.of(list);
        // 返回结果:Optional[[]]
        System.out.println(opList1.toString());
        System.out.println("---------------------");
        /**
         * add几个值进去,
         * 返回结果:Optional[[1]]
         */
        list.add(1);
        Optional<List<Integer>> opList2 = Optional.of(list);
        System.out.println(opList2.toString());
        System.out.println("---------------------");

        /**
         * ofNullable方法 为指定的值创建一个Optional,如果值为null,则返回一个空的Optional
         * 如果不为null,那么就可以给指定的值类型创建一个空的Optional对象
         * ofNullable方法 与of方法类似,唯一的区别是可以接受参数为null的情况
         */
        Optional<String> op2 = Optional.ofNullable("abc");
        System.out.println(op2.toString());
        System.out.println("---------------------");
        /**
         * 接下来返回一个为null的optional
         * 返回结果:Optional.empty
         * ofNullable与of的区别就是:ofNullable可以接收为空的值,并且返回值  Optional.empty
         */
        Optional<String> op3 = Optional.ofNullable(null);
        System.out.println(op3.toString());
        System.out.println("---------------------");

        /**
         * ifPresent:如果存在
         * 如果Optional 存在值,则为其调用consumer,否则不做处理
         * 如果存在,那么可以该参数进行操作
         */
        // 1. 创建一个不为空的集合,一个为空的集合
        List<Integer> list1 = new ArrayList<Integer>();
        for (int i = 0; i < 8; i++) {
            list1.add(i);
        }
        List<Integer> list2 = new ArrayList<Integer>();
        // 2. 创建一个consumer对象
        Consumer<List<Integer>> conList1 = list3 -> System.out.println(list3.toString());
        // 3. 创建一个Optional对象
        Optional<List<Integer>> opList03 = Optional.ofNullable(list1);
        opList03.ifPresent(conList1);
        System.out.println("--------测试完带参数的后--------------");
        Optional<List<Integer>> opList04 = Optional.ofNullable(list2);
        opList04.ifPresent(conList1);

        System.out.println("----------测试orElse方法-----------------");

        /**
         * orElse方法
         * 源码:public T orElse(T other) {
         *                  return value != null ? value : other;
         *           }
         * 如果不为null,返回value的值, 如果为null,返回其他
         */
        // 1, 定义两个String,一个为空,一个不为空
        Optional<String> optional5 = Optional.ofNullable("Hello");
        Optional<String> optional6 = Optional.ofNullable(null);
        String exceStr = "Str字符串为空,并且产生了异常";
        // 2. orElse 方法很累是  empty str ? other : str;
        // 返回结果: Hello
        System.out.println(optional5.orElse(exceStr));
        // 返回结果:Str字符串为空,并且产生了异常
        System.out.println(optional6.orElse(exceStr));
        System.out.println("--------------orElseGet()用法------------");

        /**
         * orElseGet() 方法, 与orElse 方法不同,如果为空,会返回一个supplier的函数式接口
         * orElse返回的是与Optional同类型的值
         * 而orElseGet()  方法返回的是一个Supplier, 但是Supplier()里的对象必须是参数的类本身,或是相应的子类
         */
        // 输入一个相应的字符串, 如果输入的为null, 那么随机生成一个8的字符串
        Scanner in = new Scanner(System.in);
        String str2 = "Hello World, Keep Coding";
        String str3 = null;
        //System.out.println("请输入字符串str4:");
        // 输入一个字符串
        //String str4 = in.nextLine();
        // 1. 创建一个Optional对象
        Optional opStr1 = Optional.ofNullable(str2);

        // 2. 创建一个supplier对象
        Supplier<String> supplier = () -> {

            return "This is null";
        };
        // 3. 使用orElseGet方法
        /**
         * 输入:HelloWorld
         * 返回:HelloWorld
         */
        System.out.println(opStr1.orElseGet(supplier));

        // 创建一个为空的字符串
        Optional opStr2 = Optional.ofNullable(str3);
        // 调用orElseGet方法
        // 返回结果:This is null
        System.out.println(opStr2.orElseGet(supplier));

        // 换一种更简洁的写法
        System.out.println(opStr2.orElseGet(() -> "Hello Wo.....null null"));

        System.out.println("----------orElseThrow方法------------");
        /**
         * orElseThrow用法:如果Optional不为空,返回Optional对象,如果为空就抛出异常
         * 源码中,也是调用supplier对象
         *
         */
        String str5 = null;
        String str6 = "More Null";
        // 1. 创建一个String类型的Optional对象
        Optional<String> optStr4 = Optional.ofNullable(str5);
        Optional<String> opStr3 = Optional.ofNullable(str6);
        try {
            // 测试参数为str6的Optional
            // 返回结果:More null
            System.out.println(opStr3.orElseThrow(Exception::new));
            // 测试参数为str5 的对象
            //System.out.println(optStr4.orElseThrow(() -> new NullPointerException()));
        } catch (Exception e) {
            if (str5.isEmpty()) {
                System.out.println("str5 为空");
            }
            e.printStackTrace();
        }

        System.out.println("------------------map用法-------------------");
        /**
         * T 是传入参数, U是返回类型
            public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
         *      判断mapper是否为空
         *      Objects.requireNonNull(mapper);
         *      判断本类是否不存在,如果不存在,返回empty
         *       if (!isPresent())
         *           return empty();
         *       else {
         *       返回 的类型与U的类型一直,value为T的参数
         *           return Optional.ofNullable(mapper.apply(value));
         *       }
         *   }
         */
        /**
         * map方法,如果有值,则执行Function的mapper函数,得到返回值与Optional一致
         */
        String str = "abcde";
        Optional op = Optional.ofNullable(str);
        // 如果用这种写法的话,s就是一个object类型
        Optional<Integer> map = op.map(s -> 1);
        System.out.println("map = " + map.get());
        // 写的稍微复杂一些
        Optional<Integer> map1 = op.map(
                s -> str.charAt(4) - str.charAt(0)
        );
        System.out.println("map1 = " + map1.get());
        // 先创建一个Function
        Function<String, Integer> function = s -> str.charAt(2) - str.charAt(0);
        System.out.println("map2 = " + op.map(function).get());

        /**
         * flatMap: 与map的用法相似,但是唯一不同的是,flatMap 的 mapper返回值必须是Optional
         * 调用结束时,flatMap不会对结果进行封装,如果返回的不是Optional(U) 的类型,就强制类型转换
         */
        String  str1 = "abcde";
        Optional<String> op4 = Optional.ofNullable(str1);
        // flatMap 的用法
        System.out.println("flatMap的返回结果:" +  op4.flatMap(s -> Optional.ofNullable(s + "_briup")).get());
        // map 的用法
        System.out.println("map的返回结果:" + op4.map(s -> s + "briup").get());

        System.out.println("----------filter的用法----------------");

        /**
         * filter方法: 就相当于一个筛选条件,
         * filter 调用 Predicate, 会传入一个test类型的值,
         * 然后在返回同样的Optional(U) 的类型
         *
         */
        Predicate<String> predicate = s -> s.length() > 10;
        String str4 = "abcdefg";
        Optional<String> op5 = Optional.ofNullable(str4);
        Optional<String> op6 = op5.filter(predicate);
        System.out.println(op6.orElse("str长度不超过10,所以跳到这边来了"));
        // 用更加简洁的写法来做
        Optional<String> op7 = op5.filter(s -> s.length() < 10);
        System.out.println(op7.orElse("str长度大于10 , 所以跳到这儿来了"));
    }

}

 

### 回答1: Java8中的Optional类是一个容器对象,可以包含null或非null值。它提供了一种优雅的方式来处理null值,避免了NullPointerException异常的出现。Optional类可以用于返回值、方法参数和实例变量等场景中,使代码更加简洁、清晰和安全。使用Optional类可以使代码更加健壮,减少了代码中的null检查和异常处理,提高了代码的可读性和可维护性。 ### 回答2: Optional类是Java 8中新引入的一个类,它的主要作用是在避免NullPointerException的情况下将null值返回给调用者。这个类是一个容器对象,它可以保存非空的对象,也可以保存空值(null)。 Optional类提供了通过判断一个对象是否为空来避免空指针异常的方式。它可以在代码中替换传统的null判断,这样可以更加方便地编写代码,并且可以使代码更加健壮。 在Java中,如果一个方法返回值为null,那么在调用该方法返回值的时候,会有可能抛出NullPointerException异常。而Optional类的出现可以帮助我们避免这种情况的出现,在调用Optional类的get()方法时,如果Optional类中保存的对象不为null,就会返回该对象,否则抛出一个NoSuchElementException异常。 Optional类还提供了一些方法来简化代码,比如orElse()方法,如果Optional类中保存的对象不为null,则返回该对象,否则返回指定的default值。还有ifPresent()方法,当Optional类中保存的对象不为null时,会执行指定的代码,否则不执行。 总之,Optional类是Java 8中一个很有用的类,它可以帮助我们更加方便地处理null值,避免空指针异常的出现,并且可以简化代码。但是需要注意的是,不应该滥用Optional类,因为它并不是完美的解决方案,有时候需要对null值进行特殊处理。 ### 回答3: Java 8在语言层面上增加了一个新的类:Optional。这是一个特殊的容器对象,可以包含一个null或非null的值。 Optional的目的是解决Java中的null引用问题。在Java中,如果一个变量被赋值为null,而我们试图调用该变量所对应的方法,那么就会出现NullPointerException异常。 使用Optional可以避免这种情况的发生。如果一个变量是Optional对象,那么我们必须显式地检查该对象是否包含非null的值,才能对其进行操作。这样,在我们试图调用该变量所对应的方法之前,就可以避免空指针异常的发生。 Optional类提供了很多方法来判断是否有值、获取值、如果没有值则返回默认值等等,使得我们可以更加方便地处理空值。 下面是一些Optional类提供的方法: 1. Optional.of(T value):创建一个包含非null值的Optional对象,如果T为null,则抛出NullPointerException异常。 2. Optional.ofNullable(T value):创建一个Optional对象,如果T为null,则该对象为空。 3. Optional.empty():创建一个空的Optional对象。 4. get():如果值存在,则返回该值,否则抛出异常。 5. orElse(T other):如果值存在,则返回该值,否则返回其他默认值。 6. isPresent():返回一个boolean类型的值,表示该Optional对象是否包含值。 7. ifPresent(Consumer<? super T> consumer):如果该Optional对象包含值,则对该值执行给定的操作。 在编写Java程序时,我们应该始终努力避免使用null值。使用Optional类,可以使得我们的代码更加健壮、可读性更强。但是,过多地使用Optional可能会导致代码过于冗长,所以在使用的过程中需要权衡利弊。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值