【问题标题】:Advantages of using a (flat)map over a simple null check?与简单的空检查相比,使用(平面)地图的优势?
【发布时间】:2016-05-09 11:01:32
【问题描述】:

我正在阅读下面的源代码,我想知道为什么我会使用平面图方式。正如我所看到的,实例化了更多的对象,执行的代码比通过 if 语句执行的简单 null 检查要多得多,该语句将在第一个 null 处终止,而不必费心检查其他对象,并且可以很好地整齐地放入包装器中。

在我看来,if 检查更快 + 更多内存安全(速度对我来说真的很重要,因为我通常只有 2-3 毫秒来执行大量代码,如果有的话)

使用“(flat)Map”可选方式有什么好处?我为什么要考虑改用它?

来自http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/

class Outer {
    Nested nested;
}

class Nested {
    Inner inner;
}

class Inner {
    String foo;
}

为了解析外部实例的内部字符串 foo,您必须添加多个 null 检查以防止可能的 NullPointerExceptions:

Outer outer = new Outer();
if (outer != null && outer.nested != null && outer.nested.inner != null) {
    System.out.println(outer.nested.inner.foo);
}

通过使用可选的 flatMap 操作可以获得相同的行为:

Optional.of(new Outer())
    .flatMap(o -> Optional.ofNullable(o.nested))
    .flatMap(n -> Optional.ofNullable(n.inner))
    .flatMap(i -> Optional.ofNullable(i.foo))
    .ifPresent(System.out::println);

【问题讨论】:

  • 我会使用stackoverflow.com/questions/35337020/…,即不是flatMap,而是map...
  • IMO 这只是flatMap 可以被链接的一个例子
  • @MichaelDibbets 就是这样。一方面,flatMap 绝对不是正确的操作。如果有问题,它介于map 和简单地进行null 检查之间。这是基于意见的。
  • 在我看来,创建 Optional 实例并使用神奇的流运算符比没有开销的单纯布尔检查更有效。
  • 我会做出的选择可能取决于上下文......但无论哪种方式,它都是基于意见的。这样的问题不适合 Stack Overflow。

标签: java


【解决方案1】:

我认为Optional 的使用在更广泛的流媒体环境中会更清晰,而不是单行。

假设我们正在处理 Outers 中的 ArrayList,称为 items,并且要求获取 foo 字符串的流(如果存在)。

我们可以这样做:

//bad example, read on
Stream<String> allFoos = list.stream()
            .filter(o -> o != null && o.nested != null && o.nested.inner != null)
            .map(o -> o.nested.inner.foo);

但我不得不重复一遍,关于如何从外部获取字符串(o != null &amp;&amp; o.nested != null &amp;&amp; o.nested.inner != nullo.nested.inner.foo

Stream<String> allFoos =
        list.stream()
                .map(o -> Optional.ofNullable(o)
                        .map(t -> t.nested)
                        .map(n -> n.inner)
                        .map(i -> i.foo))
                .filter(s -> s.isPresent())
                .map(s -> s.get());

这也为我提供了一种插入默认值的简单方法:

Stream<String> allFoos =
            list.stream()
                    .map(o -> Optional.ofNullable(o)
                            .map(t -> t.nested)
                            .map(n -> n.inner)
                            .map(i -> i.foo)
                            .orElse("Missing"));

替代方案可能如下所示:

//bad example (IMO)
Stream<String> allFoos = list.stream()
            .map(o -> o != null && o.nested != null && o.nested.inner != null ?
                    o.nested.inner.foo : "Missing");

【讨论】:

  • 你是什么意思,我不得不重复自己?
  • 这是一个用例,当然。
  • 它还为您提供围绕空值的类型安全性,例如我无法以错误的顺序获取平面地图,它无法编译,但我可以以错误的顺序获取 != null 测试。
  • 然而,一个好的测试套件可以使类型安全和我关于不正确的空检查顺序的观点变得多余blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html
  • @weston 你不需要使用.flatMap(t -&gt; Optional.ofNullable(t.nested) 等等来链接可选的。您可以像这样使用map 方法:.map(t -&gt; t.nested)。如果t.nested 为空,map 方法将产生一个空的可选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 2011-09-02
  • 2017-12-31
  • 1970-01-01
相关资源
最近更新 更多