我知道函数式接口意味着您可以恰好/仅有一个抽象方法和一个以上的默认方法,但我想知道如何将其与在Java中使用函数式接口的真实示例/情况联系起来。
你能给出一个有效的情况/例子吗?
提前感谢!
发布于 2019-01-02 18:04:43
首先,Java的内置函数接口Predicate、Function、Consumer等使用了注释@FunctionalInterface。
从另一方面来说,你可能想要创建你的自定义文件,如下所示:
@FunctionalInterface
public interface ThrowingConsumer<T> {
void accept(T t) throws CustomException;
}然后,您可以将其用作方法参数:
public <T, R> void doSomething(T value, ThrowingConsumer<T, R> consumer) {
// ...
}然后这样叫它:
doSomething(someValue, this::customConsumerMethodThrowingAnException);值得一提的是,@FunctionalInterface不是必需的。对于任何符合the requirements的接口,编译器都能很好地工作。
编译器处理它的方式类似于处理@Override注释。即使没有它,代码也可以编译。但一旦添加,对于将来维护代码的人来说,它会使代码更清晰、更安全。
发布于 2019-01-02 18:41:37
在JDK8之前,我们总是有函数接口,但没有lambda、方法引用等。
从JDK8开始,它们为lambda表达式和方法引用提供了目标类型,从而具有更好的可读性和更紧凑的代码。
例如,在Java-8之前,如果您想提供在每次单击Button组件时都会执行的一些逻辑,您可以这样做:
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});这是笨重,难以阅读和不够紧凑。因为根据定义,EventHandler是一个功能接口,也就是说,从jdk8开始,它有一个SAM,所以您现在可以这样做:
btn.setOnAction(event -> System.out.println("Hello World!"));您只会看到您关心的代码部分,即当单击按钮时要执行的逻辑。
此外,由于我们可以使用函数接口作为lambda表达式和方法引用的目标类型,这在以下情况下将非常有用:
List.sort、Stream.sorted、Collections.sort等。等等。
同时保持代码的可读性、紧凑和简洁性。
函数接口在Java-stream API中广泛使用。
您没有理由创建自己的功能接口,除非java.util.function没有满足您要求的功能接口,或者功能接口的名称不具有可读性,因此您可以创建自己的功能接口。
还有一个@FunctionalInterface注释推荐使用,但在创建函数接口时不是必需的(标准库经常使用它)。
这使编译器能够检查带注释的实体是否是具有单个抽象方法的接口,否则会给出错误。
这对于能够在重构代码时捕获错误也很有帮助。
发布于 2019-01-02 17:59:19
它们提供的主要用途之一是,可以使用、lambda表达式、和方法引用以及同时使用构造函数来创建函数接口的实例。例如,功能接口Sample定义为:
@FunctionalInterface
public interface Sample {
void ab();
}可以像下面这样用一行代码进行实例化:
Sample sample = () -> System.out.println("ab called");然后在需要的地方调用,如:
sample.ab();我将进一步引用java.util.function包中的Javadoc:
函数接口可以在多个上下文中提供目标类型,例如赋值上下文、方法调用或强制转换上下文:
//赋值上下文谓词p= String::isEmpty;//方法调用上下文stream.filter(e -> e.getSize() > 10)...// Cast context stream.map((ToIntFunction) e -> e.getSize())...
此外,这样的接口可以用@FunctionalInterface注解来注解。
此注释并不要求编译器将接口识别为功能接口,但只是帮助捕获设计意图,并在中寻求编译器的帮助来识别意外违反设计意图的行为。
对于将概念用于现有的这种接口也是值得注意的,
无论接口声明中是否存在FunctionalInterface注释,编译器都会将满足函数接口定义的任何接口视为函数接口。
https://stackoverflow.com/questions/54004144
复制相似问题