【问题标题】:Optional get value if present可选获取值(如果存在)
【发布时间】:2017-12-15 14:55:11
【问题描述】:

作为一个例子,我有一个这样的可选:

Optional<Desktop> opt = Optional.ofNullable(status).map(Status::getDesktop);

我想拥有桌面并在 lambda 表达式之外使用它。我是这样做的:

if (opt.isPresent()){
    Desktop desktop = opt.get();
    ...
}

有没有更好的办法获取桌面;像这样?

Desktop desktop = Optional.ofNullable(status).map(Status::getDesktop).ifPresent(get());

编辑:OrElse 是我正在寻找的方法 :)

【问题讨论】:

  • 如果desktop不存在,你希望它保持什么结果?你考虑过.orElse吗?
  • 您可以尝试Desktop desktop = Optional.ofNullable(status).map(Status::getDesktop).orElse( defaultValue );,其中defaultValue 可以是null 或可以分配给desktop 的任何其他内容,具体取决于您的需要。
  • ifPresent 是执行此操作的干净方法(您只有副作用并且没有使用该值来产生另一个值)。如果您不喜欢 lambda 或方法引用,那么 isPresent + get 是可能的最简单的程序替代方案,因此不清楚您不喜欢它的什么地方。如果您知道它存在,请不要使用Optional。如果您确定它存在或可以使用NoSuchElementException,如果不存在,请省略isPresent

标签: java lambda optional


【解决方案1】:

如果您有 Desktop 的默认值,您可以尝试使用 Optional.orElse

Desktop defaultDesktop = ...;

Desktop desktop = Optional.ofNullable(status)
    .map(Status::getDesktop)
    .orElse(defaultDesktop);

但是,您不必一定要在带有Optional.ifPresent 的 lambda 表达式中工作。您可以完美地使用接收Desktop 实例的方法,该实例将充当Optional.ifPresentConsumer 参数:

Desktop desktop = Optional.ofNullable(status)
    .map(Status::getDesktop)
    .ifPresent(this::workWithDesktop);

然后:

void workWithDesktop(Desktop desktop) {
    // do whatever you need to do with your desktop
}

如果您需要额外的参数(除了桌面本身),您可以使用 lambda 表达式来调用该方法:

String arg1 = "hello";
int arg2 = 10;

Desktop desktop = Optional.ofNullable(status)
    .map(Status::getDesktop)
    .ifPresent(desktop -> this.workWithDesktop(desktop, arg1, arg2));

然后:

void workWithDesktop(Desktop desktop, String arg1, int arg2) {
    // do whatever you need to do with your desktop, arg1 and arg2
}

【讨论】:

  • 从技术上讲,使用方法引用仍然被认为是“在 lambda 中”。与.ifPresent(desktop -&gt; { /* method body here */ });相同。
【解决方案2】:

上周有人告诉我,即使像这样使用 Optional 也是一种代码味道,所以

Desktop desktop = (status != null)? status.getDesktop() : null;

【讨论】:

  • 我不会称之为代码异味。如果有两个单线具有相同的输入和输出,那么这是一种风格或性能选择,而不是设计选择。显然,理想的情况是空安全导航运算符,但没有它你只需要选择你的毒药。
  • @MarkPeters 是的,我同意,我自己也不觉得它有什么味道,尤其是在多次被锁住的时候。还有关于 nullsafe 运算符,它是 C# 的一个不错的特性。
  • 它不像其他一些代码气味那样刺鼻,但它是一种代码气味。 Optional 不是 if/else(或等效的三元运算符)的通用替代品。
  • @VGR: "Code smell,也称为臭味,在计算机编程代码中,是指程序源代码中任何可能表明更深层次问题的症状。" 这里只是选择您想为某事使用什么衬里,并确保无论哪种方式都有参数,但它们不会超过那一行代码。如果是气味,那么更深层次的问题是什么?
  • @VGR:一个导航​​可能更难阅读。对于两个转换,您甚至不能在没有中间变量的情况下使用三元。这个论点基本上与使用 for 循环 vs 流相同,并且像那个论点一样,当某些事情“足够简单”以使用程序 for 循环时,实际上只是样式偏好的问题。除了在这种情况下,三进制已经是缺少空安全运算符的解决方法,而 for 循环被提炼为最简单的形式。
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 2017-04-03
  • 2013-02-10
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 2019-05-16
  • 2011-06-26
相关资源
最近更新 更多