如何将 Optional 转换为 OptionalInt?

2022-09-04 20:21:58

我有一个我想“转换”为,但似乎没有一个简单的方法来做到这一点。OptionalOptionalInt

以下是我想做的(人为的例子):

public OptionalInt getInt() {
    return Optional.ofNullable(someString).filter(s -> s.matches("\\d+")).mapToInt(Integer::parseInt);
}

但是,没有方法可以解决 .mapToInt()Optional

我能想到的最好的是:

return Optional.ofNullable(someString)
    .filter(s -> s.matches("\\d+"))
    .map(s -> OptionalInt.of(Integer.parseInt(s)))
    .orElse(OptionalInt.empty());

但这似乎不雅。

我是否从JDK中遗漏了一些可以使转换更加优雅的内容?


答案 1

虽然代码并不比普通条件表达式更具可读性,但有一个简单的解决方案:

public OptionalInt getInt() {
    return Stream.of(someString).filter(s -> s != null && s.matches("\\d+"))
        .mapToInt(Integer::parseInt).findAny();
}

在 Java 9 中,您可以使用

public OptionalInt getInt() {
    return Stream.ofNullable(someString).filter(s -> s.matches("\\d+"))
        .mapToInt(Integer::parseInt).findAny();
}

如前所述,两者都不比普通的条件表达式更具可读性,但我认为,它看起来仍然比使用更好(并且第一个变体不需要Java 9。mapOrElseGet


答案 2

不,没有办法使用标准的Java API以更优雅的方式做到这一点。据我所知,没有计划在JDK-9中添加这样的方法。我问保罗·桑德罗兹关于添加,等等,这是他的答案:mapToInt

我:

提供一种在 类型(如 、 等)之间进行传输的方法不是一个好主意,就像在 Stream API 中所做的那样?OptionalmapToIntmapToObj

保罗:

我不想去那里,我的回应是变成一个.添加的一个参数(请注意,原始变体返回)是可以从中组合其他功能。Optional**StreammapOrElseGetU

因此,在 Java-9 中,您可能会遇到:

return Optional.of(someString).filter(s -> s.matches("\\d+"))
     .mapOrElseGet(s -> OptionalInt.of(Integer.parseInt(s)), OptionalInt::empty);

但仅此而已。

这是因为JDK作者坚持认为该类及其原始朋友(特别是原始朋友)不应该被广泛使用,它只是一种对方法的返回值执行有限操作集的便捷方法,这些操作可能会返回“值的缺失”。此外,原始的可选选项也是为提高性能而设计的,但实际上它远不如流重要,因此使用也很好。通过Valhalla项目(希望在Java-10中实现),您将能够使用并且将变得不必要。OptionalOptional<Integer>Optional<int>OptionalInt

在您的特定情况下,更好的方法是使用三元运算符:

return someString != null && someString.matches("\\d+") ? 
       OptionalInt.of(Integer.parseInt(someString)) : OptionalInt.empty();

我假设您要从该方法返回。否则,为什么你需要它就更值得怀疑了。OptionalInt


推荐