Java 中的函数编程。方法引用与函数应用签名不匹配但成功运行
Func-Programming in Java. Method-ref doesn't match the Function apply signature yet successfully runs
我目前正在阅读 Functional Programming in Java by Venkat Subramaniam 到目前为止,它是一本很棒的书。
有一个特殊的例子让我有些困惑。在下面的代码示例中,有一个名为 setFilters(final Function<Color,Color>... filters)
的方法。
这需要一个实现函数接口的列表。在代码中使用方法引用调用 setFilters ... camera.setFilters(Color::lighter, Color::darker);
.
这令人困惑,因为 Color class 没有实现 Function 接口,也没有与 R apply(T t);
签名相匹配的方法。
我是不是漏掉了什么明显的东西?有人可以解释一下如何将 Color::darker
等传递给需要 Function<Color,Color>
的参数吗
这是完整的代码示例:
package designing.fpij;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.util.stream.Stream;
import java.util.function.Function;
import java.awt.Color;
import java.util.function.Consumer;
@SuppressWarnings("unchecked")
public class Camera {
private Function<Color, Color> filter;
public Color capture(final Color inputColor) {
final Color processedColor = filter.apply(inputColor);
return processedColor;
}
public void setFilters(final Function<Color, Color>... filters) {
filter =
Stream.of(filters).
reduce((after, before) -> filter.compose(before)).orElse(color -> color);
}
public Camera() {
setFilters();
}
public static void main(final String[] args) {
final Camera camera = new Camera();
final Consumer<String> printCaptured = (filterInfo) ->
System.out.println(String.format("with %s: %s", filterInfo, camera.capture(new Color(200, 100, 150))));
System.out.println("//" + "START:NOFILTER_OUTPUT");
printCaptured.accept("no filter");
System.out.println("//" + "END:NOFILTER_OUTPUT");
System.out.println("//" + "START:BOTH_OUTPUT");
camera.setFilters(Color::brighter, Color::darker);
printCaptured.accept("brighter & darker filter");
System.out.println("//" + "END:BOTH_OUTPUT");
}
}
Java AWT 颜色 class (docs) 有 方法 brighter()
和 darker()
,因此调用实际上传递了这些函数。
通话中
camera.setFilters(Color::darker);
相当于
setFilters(new Function<Color, Color>() {
@Override
public Color apply(Color color) {
return color.darker();
}
});
(如果您使用的是 pre-Java-8 匿名内部 类)。您可以看到,当您添加 Color 不需要是 FunctionalInterface
或实现 Function
的所有样板时 - 在更长的形式中,您将在 Function
中包装对此方法的调用.
简化对 lambda 的调用得到
setFilters((Function<Color, Color>) color -> color.darker());
甚至更短:
setFilters(color -> color.darker());
最终可以简化为您的方法参考:
setFilters(Color::darker);
我目前正在阅读 Functional Programming in Java by Venkat Subramaniam 到目前为止,它是一本很棒的书。
有一个特殊的例子让我有些困惑。在下面的代码示例中,有一个名为 setFilters(final Function<Color,Color>... filters)
的方法。
这需要一个实现函数接口的列表。在代码中使用方法引用调用 setFilters ... camera.setFilters(Color::lighter, Color::darker);
.
这令人困惑,因为 Color class 没有实现 Function 接口,也没有与 R apply(T t);
签名相匹配的方法。
我是不是漏掉了什么明显的东西?有人可以解释一下如何将 Color::darker
等传递给需要 Function<Color,Color>
这是完整的代码示例:
package designing.fpij;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.util.stream.Stream;
import java.util.function.Function;
import java.awt.Color;
import java.util.function.Consumer;
@SuppressWarnings("unchecked")
public class Camera {
private Function<Color, Color> filter;
public Color capture(final Color inputColor) {
final Color processedColor = filter.apply(inputColor);
return processedColor;
}
public void setFilters(final Function<Color, Color>... filters) {
filter =
Stream.of(filters).
reduce((after, before) -> filter.compose(before)).orElse(color -> color);
}
public Camera() {
setFilters();
}
public static void main(final String[] args) {
final Camera camera = new Camera();
final Consumer<String> printCaptured = (filterInfo) ->
System.out.println(String.format("with %s: %s", filterInfo, camera.capture(new Color(200, 100, 150))));
System.out.println("//" + "START:NOFILTER_OUTPUT");
printCaptured.accept("no filter");
System.out.println("//" + "END:NOFILTER_OUTPUT");
System.out.println("//" + "START:BOTH_OUTPUT");
camera.setFilters(Color::brighter, Color::darker);
printCaptured.accept("brighter & darker filter");
System.out.println("//" + "END:BOTH_OUTPUT");
}
}
Java AWT 颜色 class (docs) 有 方法 brighter()
和 darker()
,因此调用实际上传递了这些函数。
通话中
camera.setFilters(Color::darker);
相当于
setFilters(new Function<Color, Color>() {
@Override
public Color apply(Color color) {
return color.darker();
}
});
(如果您使用的是 pre-Java-8 匿名内部 类)。您可以看到,当您添加 Color 不需要是 FunctionalInterface
或实现 Function
的所有样板时 - 在更长的形式中,您将在 Function
中包装对此方法的调用.
简化对 lambda 的调用得到
setFilters((Function<Color, Color>) color -> color.darker());
甚至更短:
setFilters(color -> color.darker());
最终可以简化为您的方法参考:
setFilters(Color::darker);