【发布时间】:2018-01-28 02:58:50
【问题描述】:
为什么java没有选择这个签名<T> Stream <T> Stream.generate (Supplier <? extends T> supplier)而不是这个<T> Stream <T> Stream.generate (Supplier <T> supplier)?
我的意思是下面的例子(不编译)是正确的,因为字符串的提供者在字符序列流中也是有效的吗?
Supplier <String> constantHello = () -> "Hello";
long count = Stream.<CharSequence>generate(constantHello).count();
【问题讨论】:
-
如果我可以做一个编译的例子(我可以),就不会有问题了哈哈。
-
a
Supplier <String>生成在Stream <CharSequence>上下文中有效的字符串对象,因为我们可以通过CharSequence变量引用String。 -
作为为什么
Supplier<? extends T>在这里会是可取的动机,假设我有一个Supplier<PrivateFooImpl>并想从我的API 返回一个Stream<Foo>。不过,我怀疑我们是否可以轻松地回答为什么该方法被声明为这样,除非有人像 @StuartMarks 可以解释它。另请注意,您可以通过说generate(constantHello::get)或.map(s -> (CharSequence) s)来解决此问题。 -
@BoristheSpider Radiodef 的例子表明这实际上是一个合理的用例,我看不出他们不应该支持
? extends T的原因(所以+1 的问题) . @marsouf:使用::get技巧,您基本上是在创建一个具有那里所需类型的新供应商。 (一个非常简化的解释 - 引擎盖下正在进行一些非常核心的类型推断......) -
@BoristheSpider 这就是重点。如果他们写了
? extends T,那么它可能是(真实的)Stream<CharSequence>。泛型不变的要点是保持类型安全。但是由于流是“只读”的,这在这里不适用。
标签: java generics lambda java-8 java-stream