使用Optional类型,是否可能返回不同Java类型的第一个非空值?

4
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转换为U

在编译过程中:

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

在上述名称中,Long指的是Long包装类。我进行了大量研究,但没有找到类似的解决方法,希望能找到一些解决办法。将上述ID设置为相同类型对我来说不是一个选项。

当您使用.map时,流会在映射返回值上工作,因此您将实体传递给映射并映射到String,然后使用该字符串进行操作。 - R. Karlus
我认为在myFunction方法中,返回Optional<String>比返回String更好。 - Hadi J
3个回答

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

ClassWithIdAsString::getId返回的是字符串作为ID,而ClassWithIdAsLong::getId返回的是长整型作为ID,是这样吗?

如果是的话,需要颠倒过来:

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

如果两个实例都为空,则返回“”。希望您能接受这样的结果。希望这样做可以起到作用。

谢谢!它有效。作为第一个提供可行代码的答案,我会接受这个。 - rtbf

2
您的代码存在以下几个问题:
  1. 您不能将标识符 id 作为 map 操作的变量,因为它已经在封闭作用域中声明过了。
  2. orElseGet 需要一个 Supplier,但是您使用 t -> ...,这不符合 Supplier 函数接口的函数描述符。
  3. orElseGet 中的 map 操作当前返回的是一个 Optional<Long>,而不是一个 String
  4. 由于调用 map(ClassWithIdAsString::getId) 返回的是一个 Optional<String>,所以在随后的调用中使用 .map(id -> String.valueOf(id)) 调用 String.valueOf 是多余的(实际上您根本不需要执行此操作),并且仅因为重载 valueOf(Object obj) 才起作用。
以下是修复方法:
String id = instanceWithIdAsString
                .map(ClassWithIdAsString::getId)                 
                .orElseGet(() -> String.valueOf(instanceWithIdAsLong
                                       .map(ClassWithIdAsLong::getId)
                                       .orElse(-1)));

0
问题出在你对orElse子句中的可选项调用map()的最后一次调用上。由于它是一个字符串的可选项,orElse应该返回一个字符串,但是你在其中返回了一个可选项。

谢谢你的回答,但是在看到第一个带有代码的回答之后,我现在真正理解了你的意思。 - rtbf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接