Optional using a generic wild card in map and orElseGet

JTe*_*dor 5 java generics

我准备了一个小例子来复制我的项目中发生的情况。我知道如何解决它,但我很好奇为什么它甚至无法编译。问题出在最后一个返回中,当我在方法中使用通用通配符时public TestElement<?> test(),正是该行return response.map((element) -> mapAux(50L)).orElseGet(()-> orElseGetAux(20));...我不知道为什么它无法编译。我究竟做错了什么?有什么线索吗?

提前致谢!

public class FullTest {
  public static class TestElement<T>{
    public T element;

    public TestElement(T t) {
      element = t;
    }
  }

  public static <U> TestElement<U> createElement(U input) {
    return new TestElement<>(input);
  }

  private TestElement<?> mapAux(Long element){
    return new TestElement<>(element);
  }

  private TestElement<?> orElseGetAux(Integer element){
    return new TestElement<>(element);
  }

  public TestElement<?> test(){
    Optional<Long> response =  Optional.of(5L);
    return response.map((element) -> mapAux(50L)).orElseGet(()-> orElseGetAux(20));
  }
}
Run Code Online (Sandbox Code Playgroud)

更新 1 - 包含错误

我使用的是 Java 8,而不是最新版本的 IntelliJ,错误是这样的:

错误:(33, 78) java: 不兼容的类型: lambda 表达式中的返回类型错误

FullTest.TestElement<capture#1 of ?> cannot be converted to FullTest.TestElement<capture#2> of ?>
Run Code Online (Sandbox Code Playgroud)

更新 2 - 进一步说明和解决方法

使用通配符是因为我需要返回TesElement<>不同的类,这是我找到的唯一方法(在示例 Long 和 Integer 中)。我对其他选择持开放态度...

这是我更喜欢避免的可能的解决方法(这是一个例子,我知道isPresent()总是返回 true):

public TestElement<?> testWorkAround(){
    Optional<Long> response =  Optional.of(5L);
    TestElement<?> testElement;
    if(response.isPresent()){
      testElement = mapAux(response.get());
    }
    else{
      testElement = orElseGetAux(20);
    }
    return testElement;
  }
Run Code Online (Sandbox Code Playgroud)

Dan*_*non 6

你只需要明确指定它:)

public TestElement<?> test() {
   return Optional.of(5L)
       .<TestElement<?>>map(element -> mapAux(50L));
       .orElseGet(() -> orElseGetAux(20L));
}
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案。 (2认同)

tso*_*akp 0

为什么不这样做呢?

public TestElement<?> test(){
  Optional<Long> response =  Optional.of(5L);
  Optional< TestElement<?> > opResult = response.map( (element) -> mapAux(50L) );

  TestElement<?> result = opResult.orElseGet( () -> orElseGetAux(20L) );

  return result;
}
Run Code Online (Sandbox Code Playgroud)