是否可以使用Optionals为不同的Java类型返回第一个非空值?

时间:2018-01-18 21:25:25

标签: java java-8 optional

String myFunction(Optional<ClassWithIdAsString> instanceWithIdAsString, Optional<ClassWithIdAsLong> instanceWithIdAsLong) {

String resultId = instanceWithIdAsString.map(ClassWithIdAsString::getId)
                .map(id -> String.valueOf(id))
                .orElseGet(t -> instanceWithIdAsLong
                .map(ClassWithIdAsLong::getId));
return resultId;
}

上面的代码没有编译......我收到了:

  

方法引用中的返回类型错误:无法转换java.lang.String   到你

编译期间:

  

不兼容的类型:lambda表达式中不兼容的参数类型

By Long在上面的名字我的意思是长包装类。 我做了大量的研究,并没有找到类似的东西,但希望有一些解决方法。在我之上使用相同类型的id不是一个选项。

3 个答案:

答案 0 :(得分:2)

 String id = instanceWithIdAsString.map(ClassWithIdAsString::getId)
            .map(id -> String.valueOf(id))
            .orElseGet(() -> instanceWithIdAsLong
            .map(ClassWithIdAsLong::getId).orElse(""));

ClassWithIdAsString :: getId是不是返回一个String作为ID而ClassWithIdAsLong :: getId只返回ID?

如果是,则必须采用相反的方式:

String id = instanceWithIdAsString.map(ClassWithIdAsLong::getId)
            .map(id -> String.valueOf(id))
            .orElseGet(() -> instanceWithIdAsLong
            .map(ClassWithIdAsString::getId).orElse(""));

如果两个实例都为null,则返回“”。

我希望你没事。

我希望有效。

答案 1 :(得分:2)

您的代码存在一些问题:

  1. 您不能将标识符id用作map操作的变量,因为它已在封闭范围内声明。
  2. orElseGet需要Supplier,但是您正在执行的t -> ...不满足Supplier功能接口的函数描述符。
  3. map中的orElseGet操作目前正在返回Optional<Long>而不是String
  4. 如果对map(ClassWithIdAsString::getId)的调用返回Optional<String>,则在String.valueOf的后续调用中调用.map(id -> String.valueOf(id))是多余的(事实上,您不需要此操作所有)并且只是因为过载valueOf(Object obj)而工作。
  5. 所有问题都可以通过以下方式解决:

    String id = instanceWithIdAsString
                    .map(ClassWithIdAsString::getId)                 
                    .orElseGet(() -> String.valueOf(instanceWithIdAsLong
                                           .map(ClassWithIdAsLong::getId)
                                           .orElse(-1)));
    

答案 2 :(得分:0)

问题在于您最后一次调用orElse子句中可选内部的map()。由于它是字符串的可选项,orElse应返回一个字符串,但在其中返回一个可选字符串。