本文仅供学习参考!
相关教程地址:
https://www.runoob.com/java/java8-functional-interfaces.html
https://www.cnblogs.com/dgwblog/p/11739500.html
https://www.developer.com/java/java-functional-interfaces/
接口是定义一组方法及其签名的契约。任何类都可以扩展该接口并实现该接口的方法。Java 编程语言从该语言的最早版本开始就提供了对接口的支持。
函数式接口是 Java 的一个流行功能,在版本 8 中添加到Java语言中。它们允许开发人员将函数创建为一流对象,这为创建可重用代码和简化开发过程开辟了新的可能性。
本文将介绍函数式接口、它们如何工作、它们为何有用,以及开发人员如何在项目中使用它们的一些示例。
Java 中的函数式接口是什么?
Java 中的函数式接口是仅由一个抽象方法(即未实现的方法)组成的接口。尽管此方法必须有返回类型,但它不能接受参数。该方法还必须是公共的并且位于可访问的类或接口中。
除了一种抽象方法之外,您还可以在 Java 的函数式接口中创建以下方法:
- 默认方法
- 静态方法
- 从Object类继承的方法
下面是 Java 函数式接口的简单代码示例:
@FunctionalInterface
public interface MyFunctionalInterface
{
void doSomething();
}
如您所见,该接口只有一个抽象方法。
如何用 Java 编写比较器接口
函数式接口的一个常见示例是Comparator接口,它用于比较两个对象。它有以下抽象方法:
int compare(T obj1, T obj2);
Here's how the Comparer interface is defined in Java:
@FunctionalInterface
public interface Comparator {
int compare(T o1, T o2);
boolean equals(Object obj);
//其他方法...
}
Comparator接口可用于按对象的自然顺序或您定义的自定义顺序对对象列表进行排序**。例如,程序员可以使用Comparator**接口按字符串的长度对字符串列表进行排序:
List listStrings = Arrays.asList("ABC", "XYZ", "PQR");
listStrings.sort((s1, s2) -> s1.length() - s2.length());
System.out.println(listStrings);
您还可以颠倒列表的顺序:
listStrings.sort((s1, s2) -> s2.length() - s1.length());
System.out.println(listStrings);
Java中的@FunctionalInterface注解
在 Java 8 中,注释**@FunctionalInterface**将接口标记为函数式接口。如果您的接口包含多个抽象方法,您可以使用此注释来标记接口以生成编译器错误。Java 中的函数式接口经常在lambda 表达式中使用,它可以有多个默认方法。
需要注意的是,注解**@FunctionalInterface是可选的。如果一个接口包含一个抽象方法但没有@FunctionalInterface**注解,那么它仍然是一个函数式接口,并且可能是 lambda 表达式的目标类型。该注释可以防止我们错误地将函数式接口修改为非函数式接口,因为编译器会标记错误。
Java 中函数式接口有哪些好处?
函数式接口最显着的好处是,它们可以创建多个类可以使用的抽象,而无需复制和粘贴代码。当开发人员需要使用各种方法和行为创建复杂的抽象时,这尤其有用。
在 Java 中,使用函数式接口,程序员可以将函数作为参数而不是引用对象传递,这减少了必须编写的样板代码量。
在函数式编程中,一段代码可以被视为数据。这就是 lambda 表达式发挥作用的地方。您可以使用 lambda 表达式将代码传递给另一个函数或对象。
应该注意的是,lambda 表达式使用函数式接口作为数据类型。因为函数式接口中只有一个抽象方法,所以该方法的实现就成为可以作为参数传递给另一个方法的代码。
使用匿名内部类实现函数式接口
如下代码示例所示,在 Java 8 之前,程序员使用匿名内部类或对象来实现此类接口:
class Test {
public static void main(String args[])
{
new Thread(new Runnable() {
@Override public void run()
{
System.out.println("Hello World!");
}
}).start();
}
}
Java 中的内置函数式接口
除了Comparator和Runnable接口之外,Java 8 中还有许多其他内置的函数式接口,例如Callable、Predicate、Function和Consumer。这些接口可以在java.util.function包中找到。
下面简单讨论一下Java中最常用的内置接口:
- 比较器:比较器是一个接口,用于根据特定标准比较两个对象。java.util.Comparator类用于实现该接口。
- Runnable:它是一个抽象类,实现Runnable接口并提供运行线程的抽象。
- Callable:它表示一个返回单个结果值T的任务,可以通过调用其**call()**方法来访问该结果值。
- Future:Future表示一个异步操作,其结果可能尚不可用,但最终将在未来某个时间点(当所有挂起的活动已成功或不成功完成时)变得可用。
- 供应商:供应商只是一个返回值而不接受输入参数的函数;这些也称为纯函数。
- Predicate:Predicate功能接口表示对于由布尔参数类型T指定的某些条件返回true或false的谓词。
- Consumer:Consumer函数接口表示接受T类型参数且不返回结果的函数。
如何用 Java 实现自定义功能接口
函数式接口可以通过两种方式创建:通过添加**@FunctionalInterface注解,可以将现有接口转换为函数式接口。或者,程序员可以拥有一个仅包含一个抽象方法的接口。以下代码示例是一个完整的示例,说明了如何在 Java 中定义和使用函数式接口:**
@FunctionalInterface
interface Test{
void display(String message);
}
public class TestImplementation implements Test{
public void display(String message){
System.out.println(message);
}
public static void main(String[] args) {
TestImplementation obj = new TestImplementation();
obj.display("Hello World!");
}
}
END
Java 8 中引入的 lambda 表达式比早期版本提供了新的语法改进,并有助于消除应用程序中的样板代码。函数式接口是 Java 的一等公民,它们的实现可以被视为 lambda 表达式。函数式接口通过减少匿名内部类的冗长性,使编写函数式代码变得更加容易。
函数式接口是为代码添加灵活性的好方法。通过使用功能接口,编码人员可以准确指定您需要从对象中获得哪些功能,然后让该对象由满足您的要求的任何类实现。