Arj*_*jun 3 java generics java-stream
许多Java Stream接口方法在参数中使用下界通配符
例如
Stream<T> filter(Predicate<? super T> pred)
Run Code Online (Sandbox Code Playgroud)
和
void forEach(Consumer<? super T> action)
Run Code Online (Sandbox Code Playgroud)
Predicate<? super T>在Predicate<T>这里使用的好处是什么?
我知道,Predicate<? super T>可以将T和超级类型的谓词对象作为参数传递给方法,但是我无法想到在特定类型上需要超级类型的谓词的情况?
例如,如果我有一个Stream<Integer>i,则可以将Predicate<Integer>, Predicate<Number>, and Predicate<Object>对象作为参数传递给它的filter方法,但是为什么有人会传递Predicate<Object>over Predicate<Integer>?在这里
使用的好处是<? super T>什么?
我假设您知道PECS模式,即使没有实际用例进入您的视线,在设计API时也要遵守该模式。当我们查看Java 8的最终状态和典型用例时,很容易以为不再需要它了。即使实际上使用更通用的类型时,lambda表达式和方法引用不仅可以推断目标类型,而且改进的类型推断也适用于方法调用。例如
Stream.of("a", "b", "c").filter(Predicate.isEqual("b"));
Run Code Online (Sandbox Code Playgroud)
将需要filter(Predicate<? super T>)使用Java 8之前的编译器进行声明,因为它将推断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);
Run Code Online (Sandbox Code Playgroud)
仅当filter被声明为时才有效filter(Predicate<? super T> predicate)。或者您为Stream强制使用其他元素类型,
Predicate<Number> name = n -> n.doubleValue()>=10;
Stream.<Number>of(10, 12.5).filter(name);
Run Code Online (Sandbox Code Playgroud)
这已经演示了如何省略? super的filter声明可能对主叫方的一侧更冗长。另外,如果在后续的管道阶段中需要更具体的类型,则强制执行更一般的元素类型可能不是一种选择。
现有功能的实现很少见,但也有一些实现,例如
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();
Run Code Online (Sandbox Code Playgroud)
就没有不行? super的forEach(Consumer<? super T> action)声明。
您可能经常遇到的一个情况是拥有一个现有的Comparator实现,您可能希望将该实现传递给sorted具有更特定元素类型的Stream方法,例如,
Stream.of("FOO", "bar", "Baz")
.sorted(Collator.getInstance())
.forEachOrdered(System.out::println);
Run Code Online (Sandbox Code Playgroud)
就没有不行? super的sorted(Comparator<? super T> comparator)声明。
| 归档时间: |
|
| 查看次数: |
262 次 |
| 最近记录: |