【问题标题】:Guava Optional type, when transformation returns another OptionalGuava Optional 类型,当转换返回另一个 Optional
【发布时间】:2012-10-25 14:44:18
【问题描述】:

我有一个产生Optional<String>的方法

但是这个 String 必须在另一个应用程序级别解析为 Integer 或 Long。

我有一个Function<String, Integer> 可以应用于字符串,以产生一个整数。 此转换可能会失败,因为 String 可能不是 Integer 可解析值。


我想在转换失败时返回 Optional,而不是抛出解析异常。

我不能让 STRING_TO_INTEGER_FUNCTION 返回 null,因为 Guava 不允许这样做:

Exception in thread "main" java.lang.NullPointerException: Transformation function cannot return null.

因此,我唯一能做的就是拥有一个Function<String,Optional<Integer>>,但最终结果是Optional<Optional<Integer>>,这并不是很酷,因为我可能需要对其应用其他转换。


有人知道我如何在 Guava 中做类似的事情吗?

Optional.of("Toto").transform(STRING_TO_INTEGER_FUNCTION) = // Optional<Integer> ?

谢谢

【问题讨论】:

    标签: java generics guava


    【解决方案1】:

    我猜你可以做到:

    public static void main(final String[] args) {
      final Optional<Integer> valid = Optional.of("42")
          .transform(STR_TO_INT_FUNCTION)
          .or(Optional.<Integer>absent());
      System.out.println(valid); // Optional.of(42)
      final Optional<Integer> invalid = Optional.of("Toto")
          .transform(STR_TO_INT_FUNCTION)
          .or(Optional.<Integer>absent());
      System.out.println(invalid); // Optional.absent()
      final Optional<Integer> absent = Optional.<String>absent()
          .transform(STR_TO_INT_FUNCTION)
          .or(Optional.<Integer>absent());
      System.out.println(absent); // Optional.absent()
    }
    
    private static final Function<String, Optional<Integer>> STR_TO_INT_FUNCTION =
        new Function<String, Optional<Integer>>() {
          @Override
          public Optional<Integer> apply(final String input) {
            return Optional.fromNullable(Ints.tryParse(input));
          }
        };
    

    当您使用 Optional -> transform -> 或在一行中(分配转换后的可选整数将产生 Optional&lt;Optional&lt;Integer&gt;&gt;)时, 的用法并不笨拙。

    【讨论】:

    • 问题是,如果我最初的 Optional 不存在,我会在 get 调用中遇到异常:(
    • 是的,修复了这个问题,但现在有点不可读了...在转换后使用.or(Optional.&lt;Integer&gt;absent()) 而不是get()。您可能应该制作一些静态辅助方法来隐藏转换和或。
    【解决方案2】:

    使用Optional.transform 似乎与可​​能失败的转换不兼容 - 从理论上讲,这意味着 optional 可选,当您想要做的是合并缺勤时。我建议使用类似以下的内容:

    Optional<String> strOptional = Optional.of("Toto");
    Optional<Integer> intOptional =
            strOptional.isPresent()
            ? Optional.fromNullable(Ints.tryParse(strOptional.get()))
            : Optional.<Integer>absent();
    

    【讨论】:

      【解决方案3】:

      除上述之外的其他选项:

      • 使用普通的旧 if/else(Guava 团队建议不要过度使用此类结构,遵循这些建议通常是明智之举 - 否则您将不会节省太多代码行并降低可读性)
      • 使用肮脏的把戏:from(singleton("Toto")).transform(STRING_TO_INTEGER_FUNCTION).filter(notNull()).first().orNull() - 只是假设的想法,恕我直言,它的可读性也很差。至少它不包含泛型、?: 运算符或匿名类,但代价是更多的静态导入。
      • 等待 Java 8,其中 Optional.map 允许空转换结果

      您可以为http://code.google.com/p/guava-libraries/issues/detail?id=1171 投票。不幸的是,Guava 团队似乎对将这个问题转化为某种结果犹豫不决。

      【讨论】:

        猜你喜欢
        • 2021-02-06
        • 2021-10-09
        • 1970-01-01
        • 2022-01-06
        • 2021-06-10
        • 1970-01-01
        • 2019-11-15
        • 2019-06-12
        • 2015-03-06
        相关资源
        最近更新 更多