繁体   English   中英

为什么许多Java Stream接口方法在参数中使用较低的有界通配符而不是泛型类型?

[英]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 ? superforEach(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM