【问题标题】:Can I not map/flatMap an OptionalInt?我不能映射/flatMap 一个 OptionalInt 吗?
【发布时间】:2015-03-17 16:48:45
【问题描述】:

为什么在 OptionalInt 或其他原始可选风格上似乎没有 map()/flatMap() 方法?

stream() 映射操作允许在对象和基元之间进行转换。但是为什么 Optional 不利用这个呢?

OptionalInt profileId = OptionalInt.of(124);

Optional<Profile> profile = profileId.map(i -> getProfile(i));  //no such valid map() method!

【问题讨论】:

  • 无论出于何种原因,他们决定不将这些操作包含在 Optional 的原始风格中。
  • 但是实现一个将 OptionalInt 转换为 Optional 的方法会阻止什么? Stream 做了类似我想象的事情。
  • 也许是为了保持轻量级而忽略了它,因为这是原语的重点?必须有几种 map 和 flatmap 方法的变体来适应其他原始可选风格以及标准对象 Optional。
  • map 的返回值是另一种可选的,不是Profile 不是吗?
  • 我不知道原因,但您可以将您的 OptionalInt 包裹在 Optional 中:Profile profile = Optional.of(profileId).filter(OptionalInt::isPresent).map(opt -&gt; getProfile(opt.getAsInt())).orElseThrow(...);。否则使用Optional&lt;Integer&gt;

标签: java lambda java-8


【解决方案1】:

原始选项没有 mapflatMapfilter 方法。

此外,根据Java8 in Action p.305,您不应该使用它们。 在流上使用原语的理由是性能原因。在大量元素的情况下,装箱/拆箱开销很大。但这是毫无意义的,因为 Optional 中只有一个元素。

此外,考虑示例:

public class Foo {
    public Optional<Integer> someMethod() {
        return Optional.of(42);
    }
}

以及作为方法参考的用法:

.stream()
.map(Foo::someMethod)

如果将 someMethod 的返回类型更改为 OptionalInt

public OptionalInt someMethod() {
    return OptionalInt.of(42);
}

您不能将其用作方法引用,代码将无法编译:

.map(Foo::someMethod)

【讨论】:

  • 我不明白你的例子的意义。 someMethod 返回OptionalInt,你可以映射它,它会将Stream&lt;Foo&gt; 转换为Stream&lt;OptionalInt&gt;(而不是第一种情况下的Stream&lt;Optional&lt;Integer&gt;&gt;)。性能论点也不成立。 StreamOptional 上的操作也是关于组合的。我可以在Streamstream.reduce(binOp).map(fun),但我不能在IntStream 上这样做。缺乏一致性很烦人。至少可以有一个Optional&lt;Integer&gt; boxed(),就像IntStream一样......
  • 也许从一个 OptionalInt 到另一个的“映射”并不是那么有用。但是'mapToObject'是。 OptionalInt x = ...; x.mapToObject(Integer::toString).orElse(""); 会很有用。或者您希望将 OptionalInt 带入 Option 的任何其他情况
  • “你不应该使用它们”但是 Java API 有返回它们的方法,比如 IntStream.max()
  • “你不应该使用它们”对我来说没有说服力。引用另一本书,Joshua Bloch 的 Effective Java,第 3 版在第 55 项中说:“......你永远不应该返回盒装原始类型的可选项,除了次要的原始类型,Boolean、Byte、Character、Short , 和浮动”
【解决方案2】:

似乎在 Java 9 中 OptionalInt 将有一个 stream 方法,它会为您提供一个 IntStream ,其中包含 0 或 1 个元素。在这个流上你当然可以使用map()flatMap()filter() 等。

对于 Java 8,我没有什么可以添加到 user2138356’s answer

【讨论】:

    猜你喜欢
    • 2020-10-16
    • 1970-01-01
    • 2014-07-12
    • 2023-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多