ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 8 开始新增的 Optional 类 - Optional 中的方法

2022-05-17 21:31:31  阅读:163  来源: 互联网

标签:Java orElseGet 对象 方法 新增 Optional orElse name


fPresent() 的使用条件

ifPresent() 方法能够让我们在对对象进行下一步操作之前判断我们需要操作的对象是否为 Null,在没有 Optional 对象之前,我们通常使用下面的方法先进行判断:

if(name != null) {
    System.out.println(name.length());
}

上面的程序逻辑是,首先判断 name 这个变量是不是为空,如果不为空的话,允许程序继续执行下一步。

这种判断方法不是很美观,代码也比较难看,更重要的是这种判断方法也是容易出错的。

有谁又能够保证我们在检查空,并且打印出变量后,这个变量不被再次使用呢,在这个变量再次使用的时候又有谁能够保证我们不会忘记空检查呢?

同时,有可能在程序的运行时导致空对象异常,NullPointerException。尤其是在程序因为输入的问题导致失败,无法启动的情况下,通常这种情况是因为程序本身没有被很好的设计和编码。

Optional 能够非常明确的处理可能为空的变量,这个是一种比较好的编码习惯。

让我们看看上面的代码在 Java 8 的环境下是如何进行实现的。

在常用的函数编程的情况下,我们在对象不进行空检查后使用函数式进行编程:

    @Test
    public void givenOptional_whenIfPresentWorks_thenCorrect() {
        Optional<String> opt = Optional.of("HoneyMoose");
        opt.ifPresent(name -> LOG.debug("{}", name.length()));
    }

在上面的示例中,我们仅仅使用了 2 行代码就实现了第一种方法需要使用的 5 行代码。

第一行代码使用 Optional 对象来对我们的变量进行包装,第二行代码就对已经包装好的 Optional 对象进行相应的操作。

orElse() 方法来定义默认值

orElse() 这个方法被用来获取 Optional 实例中内部的值。

这个方法只需要 1 个参数,如果 Optional 对象中的值不为空的话,程序将会返回 Optional 对象中的值,否则将会使用 orElse 这个方法中输入参数的值来替代输出。

当然,你也可以在 orElse() 调用一个方法,至于和 orElseGet() 有什么不同,我们将会在后面进行说明。

考察下面的代码:

    @Test
    public void whenOrElseWorks_thenCorrect() {
        String nullName = null;
        String name = Optional.ofNullable(nullName).orElse("john");
        assertEquals("john", name);
    }

orElseGet() 方法来定义默认值

orElseGet()orElse() 方法类似。

我们都知道,如果 Optional 为空的时候,如果使用 orElse() 方法,将会使用这个方法中输入的参数来替代返回,orElseGet() 就更近一步了。

orElseGet 提供的是一个函数式的接口,你可以在 orElseGet() 中使用函数编程,返回的结果就是这个函数进行运算后的结果。

    @Test
    public void whenOrElseGetWorks_thenCorrect() {
        String nullName = null;
        String name = Optional.ofNullable(nullName).orElseGet(() -> "john");
        assertEquals("john", name);
    }

orElse() 和 orElseGet() 方法的对比

和很多程序员一样,如果你是开始接触 Java 8 的话,你可能对 orElse()orElseGet() 2 个方法之间的执行不同有所不了解,觉得这 2 个方法在功能上都是重复的。

 

1_JahdNdHZ2myDp5dSv9KIxA

 

事实上看起来就是这样的,但是在实际上还是有一些微妙的不同的。

如果你对这些细微的不同不够了解的话,有可能会严重影响你程序的执行效率。

简单来说就是其中定义的函数是否被执行的区别,不管前面对 Optional 的判断是否为 null, orElse() 中调用的方法都会被执行,orElseGet() 却不会。

首先,让我们在测试类中定义一个 getMyDefault() 方法,这个方法不使用任何参数,只是打印并且返回一个字符串:

public String getMyDefault() {
    System.out.println("Getting Default Value");
    return "Default Value";
}

然后我们分别使用 orElse()orElseGet() 来进行调用这个方法,我们来看看有什么不同。

Optional 对象为空的情况

@Test
public void whenOrElseGetAndOrElseOverlap_thenCorrect() {
    String text = null;

    String defaultText = Optional.ofNullable(text).orElseGet(this::getMyDefault);
    assertEquals("Default Value", defaultText);

    defaultText = Optional.ofNullable(text).orElse(getMyDefault());
    assertEquals("Default Value", defaultText);
}

正如我们所看到的,因为 Optional 对象为空,我们定义的函数都被调用了。

程序的输出如下,从程序的输出可以看出来,这 2 个方法的执行是相同的。

The side effect is:

Getting default value...
Getting default value...

Optional 对象不(NOT)为空的情况

使用上面相同的代码,但是这次不同的是,我们定义的 Optional 对象是不为空的

    @Test
    public void whenOrElseGetAndOrElseDiffer_thenCorrect() {
        String text = "Text present";
        LOG.debug("Using orElseGet:");
        String defaultText = Optional.ofNullable(text).orElseGet(this::getMyDefault);
        assertEquals("Text present", defaultText);

        LOG.debug("Using orElse:");
        defaultText = Optional.ofNullable(text).orElse(getMyDefault());
        assertEquals("Text present", defaultText);
    }

如上面的代码所展示的,我们需要判断的 Optional 对象已经不为空了,程序的输出如下所示:

Using orElseGet:
Using orElse:
Getting default value...

注意到 orElseGet() 方法在我们检查 Optional 对象不为空的时候,就不再调用 getMyDefault 这个方法。

然后我们再来看看 orElse() 这个方法,尽管 Optional 对象不为空,但是 orElse() 这个方法中调用的方法还是被执行了一次。

如果是创建对象的话,那么我们就创建了一个从来没有使用过的对象,在 JVM 的垃圾回收下,这个被创建的对象随后就被回收销毁了。

考虑一种极端的情况,如果我们定义的 getMyDefault() 方法不是创建对象并且销毁这么简单,假设我们需要进行数据库查询,或者 HTTP 访问等,这个将会导致程序有很大的开销。

通常我们都知道,在数据库查询的时候,创建数据库连接是很消耗资源的。

因此这就是这个 2 个方法在使用时候的区别,主要区别就在 Optional 对象不为空的情况。

 

https://www.ossez.com/t/java-8-optional-optional/13967

标签:Java,orElseGet,对象,方法,新增,Optional,orElse,name
来源: https://www.cnblogs.com/huyuchengus/p/16282464.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有