简体   繁体   English

函数输入类型的通用有界通配符

[英]Generic bounded wildcard of function input type

While reading the Stream interface source code I found this method signature: 在阅读Stream接口源代码时,我发现了这个方法签名:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

I wonder why the input type of mapper is ? super T 我想知道为什么mapper的输入类型是? super T ? super T while the output type is ? extends R ? super T而输出类型是? extends R ? extends R , why not use ? extends ? extends R ,为什么不使用? extends ? extends for both? 两者都? extends

Consider you want to map a CharSequence to another CharSequence (thus T = R = CharSequence ). 考虑您要将CharSequence映射到另一个CharSequence (因此T = R = CharSequence )。 Which functions will work for you? 哪些功能适合您?

Function<Object, String> fn1 = Object::toString;

Is it good for you? 对你有好处吗? Yes, because it can take any CharSequence (which is also Object ) and convert it to the String (which is also CharSequence ). 是的,因为它可以采用任何 CharSequence (也是Object )并将其转换为String (也是CharSequence )。

Function<CharSequence, StringBuilder> fn2 = StringBuilder::new;

Is it good for you? 对你有好处吗? Yes, because it can take any CharSequence and convert it to the StringBuilder (which is also CharSequence ). 是的,因为它可以接受任何 CharSequence并将其转换为StringBuilder (也是CharSequence )。

Function<String, String> fn3 = String::trim;

Is it good for you? 对你有好处吗? No, because it cannot take any CharSequence , only some of them. 不,因为它不能接受任何 CharSequence ,只有其中一些。

Thus you can see that first type argument must be CharSequence or any superclass, but second must be CharSequence or any subclass. 因此,您可以看到第一个类型参数必须是CharSequence或任何超类,但第二个必须是CharSequence或任何子类。

Because of PECS :) - Producer Extends, Consumer Super 因为PECS :) - Producer Extends,Consumer Super

Producer Extends - If you need a List to produce T values (you want to read Ts from the list), you need to declare it with ? extends T 生产者扩展 - 如果您需要一个List来生成T值(您想从列表中读取Ts),您需要声明它? extends T ? extends T

Consumer Super - If you need a List to consume T values (you want to write Ts into the list), you need to declare it with ? super T 消费者超级 - 如果你需要一个List消耗T值(你想把Ts写入列表),你需要声明它? super T ? super T

There is a rule of thumb which was first mentionned by Joshua Bloch in his Effective Java book which stands as PECS . Joshua Bloch在他的Effective Java书中首次提到了一个经验法则,即PECS

  • PE Producer extends PE制作人延伸
  • CS Consumer super CS消费者超级

This function produce a result (? extends R) from what it received ( ? super T ). 该函数从接收到的结果( ? super T )产生结果(? extends R) )。

The documentation of java.util.Function is kinda clear on that : java.util.Function的文档有点清楚:

Represents a function that accepts one argument and produces a result. 表示接受一个参数并生成结果的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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