[英]Why many Java Stream interface methods use lower bounded wildcard in parameters instead of generic type?
许多Java Stream接口方法在参数中使用较低的有界通配符
例如
Stream<T> filter(Predicate<? super T> pred)
和
void forEach(Consumer<? super T> action)
使用Predicate<? super T>
什么好处Predicate<? super T>
Predicate<? super T>
over Predicate<T>
在这里?
我理解, Predicate<? super T>
Predicate<? super T>
作为参数,T和超类型的Predicate对象可以传递给方法,但是我不能想到超类型的Predicate需要超过特定类型的情况?
例如,如果我有一个Stream<Integer>
我可以将Predicate<Integer>, Predicate<Number>, and Predicate<Object>
对象作为其过滤方法的参数传递,但为什么有人会通过Predicate<Integer>
传递Predicate<Object>
Predicate<Integer>
?
使用<? super T>
什么好处<? super T>
<? super T>
在这?
我假设您了解PECS模式,这在设计API时非常有用,即使没有实际的用例会突然出现。 当我们查看Java 8的最终状态和典型用例时,很容易认为不再需要它了。 即使实际使用更通用的类型,lambda表达式和方法引用不仅会推断目标类型,而且改进的类型推断也适用于方法调用。 例如
Stream.of("a", "b", "c").filter(Predicate.isEqual("b"));
需要使用pre-Java 8编译器的filter(Predicate<? super T>)
声明,因为它会推断Predicate<Object>
表达式Predicate.isEqual("b")
。 但是对于Java 8,它也可以使用Predicate<T>
作为参数类型,因为目标类型也用于嵌套方法调用。
我们可能会认为Stream API的开发和新的Java语言版本/编译器实现同时发生,因此可能有一个实际的理由在开始时使用PECS模式,而从来没有理由不使用那种模式。 在重用现有的谓词,函数或消费者实例时,它仍然提高了灵活性,即使这可能不是很常见,也不会造成伤害。
请注意,虽然例如Stream.of(10, 12.5).filter(n -> n.doubleValue() >= 10)
,但是,因为谓词可能得到一个适合处理Stream的元素类型的推断的非可表示类型“ #1 extends Number & Comparable<#1>
“,您不能声明该类型的变量。 如果要将谓词存储在变量中,则必须使用,例如
Predicate<Number> name = n -> n.doubleValue()>=10;
Stream.of(10, 12.5).filter(name);
如果filter
已声明为filter(Predicate<? super T> predicate)
,则只能起作用。 或者您为Stream强制使用不同的元素类型,
Predicate<Number> name = n -> n.doubleValue()>=10;
Stream.<Number>of(10, 12.5).filter(name);
哪个已经演示了如何省略? super
filter
声明中的? super
可能会导致调用方更加冗长。 此外,如果在以后的管道阶段中需要更具体的类型,则强制执行更通用的元素类型可能不是一种选择。
虽然现有的功能实现很少见,但有一些例如
Stream.Builder<Number> b = Stream.builder();
IntStream.range(0, 10).boxed().forEach(b);
LongStream.range(0, 10).boxed().forEach(b);
Stream<Number> s = b.build();
如果没有? super
? super
在forEach(Consumer<? super T> action)
声明中。
您可能经常遇到的情况是,您可能希望将现有的Comparator
实现传递给具有更具体元素类型的Stream的已sorted
方法,例如,
Stream.of("FOO", "bar", "Baz")
.sorted(Collator.getInstance())
.forEachOrdered(System.out::println);
如果没有? super
? super
sorted(Comparator<? super T> comparator)
声明。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.