java 8选项列表收集列表编译错误 [英] java 8 list of optionals collect to list compilation error

查看:109
本文介绍了java 8选项列表收集列表编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解

Stream<Optional<Integer>> optionalStream = Stream.of(
                Optional.of(1),
                Optional.empty(),
                Optional.of(5));

List<Optional<Integer>> optionalList = optionalStream.collect(Collectors.toList());

哪个工作正常并且:

List<Optional<Integer>> optionalList1 = Stream.of(
                Optional.of(1),
                Optional.empty(),
                Optional.of(5)).collect(Collectors.toList());

我收到错误的地方

Error:(138, 40) java: incompatible types: inference variable T has incompatible bounds
    equality constraints: java.util.Optional<java.lang.Integer>
    lower bounds: java.util.Optional<? extends java.lang.Object>


推荐答案

我已经减少了一些示例,并尝试过使用 -XDverboseResolution = all 编译以输出有关类型推断的信息:

I've reduced the examples a bit, and tried to compile the with -XDverboseResolution=all to output information about the type inference:

final class One {
  void one() {
    Stream<Optional<Integer>> optionalStream = Stream.of(Optional.empty());
    List<Optional<Integer>> optionalList = optionalStream.collect(Collectors.toList());
  }
}

final class Two {
  void two() {
    List<Optional<Integer>> optionalList1 =
        Stream.of(Optional.empty()).collect(Collectors.toList());
  }
}

如果 2 ,看起来像 Stream.of 的延迟实例化甚至在查看后续 collect

In the case of Two, it looks like the deferred instantiation of Stream.of is done before even looking at the subsequent collect:

...
Two.java:9: Note: Deferred instantiation of method <T>of(T)
        Stream.of(Optional.empty()).collect(Collectors.toList());
                 ^
  instantiated signature: (Optional<Object>)Stream<Optional<Object>>
  target-type: <none>
  where T is a type-variable:
    T extends Object declared in method <T>of(T)
Two.java:9: Note: resolving method collect in type Stream to candidate 0
        Stream.of(Optional.empty()).collect(Collectors.toList());
...

(解决方法收集是第一次提到收集

(the "resolving method collect is the first mention of collect)

没有目标-type 来限制它;实例化的签名显示它是 Stream< Optional< Object>>

There is no target-type to constrain it; the instantiated signature shows that it's a Stream<Optional<Object>>.

如果您查看一个的相应输出:

If you look at the corresponding output for One:

...
One.java:8: Note: Deferred instantiation of method <T>of(T)
    Stream<Optional<Integer>> optionalStream = Stream.of(Optional.empty());
                                                        ^
  instantiated signature: (Optional<Integer>)Stream<Optional<Integer>>
  target-type: Stream<Optional<Integer>>
  where T is a type-variable:
    T extends Object declared in method <T>of(T)
...

它是正确的,因为它知道目标类型。

It gets this right because it knows a target type.

我不能确切地说为什么延迟实例化在此时发生 Two ,因为我对应用类型推断的方式不太熟悉。

I can't say exactly why the deferred instantiation occurs at this point for Two, as I'm not familiar enough with the way the type inference is applied.

认为这是因为 Stream.of 的调用不被视为多重表达,但是我无法真正说服自己为什么(请参阅编辑历史记录中的一些不连贯的乱码)。

I think it's because the invocation of Stream.of isn't considered a poly expression, but I can't really convince myself why (see edit history for some incoherent ramblings).

我建议的修正是将类型提示应用于 Optional.empty(),即可选。< Integer> empty() 。这具有在推理的早期获得 Optional 的实际类型的效果,因此在延迟实例化时已知事件,尽管目标类型仍然是未知:

The fix I'd suggest is to apply a type hint to the Optional.empty(), i.e. Optional.<Integer>empty(). This has the effect of getting the actual type of the Optional right earlier in the inference, so it is known at the time of the deferred instantiation, event though the target type is still unknown:

final class Three {
  void three() {
    List<Optional<Integer>> optionalList1 =
        Stream.of(Optional.<Integer>empty()).collect(Collectors.toList());
  }
}

...
Three.java:9: Note: resolving method of in type Stream to candidate 1
        Stream.of(Optional.<Integer>empty()).collect(Collectors.toList());
              ^
  phase: BASIC
  with actuals: Optional<Integer>
  with type-args: no arguments
  candidates:
      #0 not applicable method found: <T#1>of(T#1...)
        (cannot infer type-variable(s) T#1
          (argument mismatch; Optional<Integer> cannot be converted to T#1[]))
      #1 applicable method found: <T#2>of(T#2)
        (partially instantiated to: (Optional<Integer>)Stream<Optional<Integer>>)
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#1>of(T#1...)
    T#2 extends Object declared in method <T#2>of(T#2)
Three.java:9: Note: Deferred instantiation of method <T>of(T)
        Stream.of(Optional.<Integer>empty()).collect(Collectors.toList());
                 ^
  instantiated signature: (Optional<Integer>)Stream<Optional<Integer>>
  target-type: <none>
  where T is a type-variable:
    T extends Object declared in method <T>of(T)
...

这篇关于java 8选项列表收集列表编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆