Java函数接口
Java函数接口一词是在Java 8中引入的。Java中的函数接口是仅包含一个抽象(未实现)方法的接口。除了单个未实现的方法之外,函数接口还可以包含具有实现的默认方法和静态方法。
这是一个Java函数接口示例:
public interface MyFunctionalInterface { public void execute(); }
上面的代码被视为Java中的函数接口,因为它仅包含一个方法,并且该方法没有实现。通常,Java接口不包含其声明的方法的实现,但可以包含默认方法或者静态方法的实现。下面是Java函数接口的另一个示例,其中包含一些方法的实现:
public interface MyFunctionalInterface2{ public void execute(); public default void print(String text) { System.out.println(text); } public static void print(String text, PrintWriter writer) throws IOException { writer.write(text); } }
上面的接口在Java中仍然算作函数接口,因为它仅包含一个未实现的方法。
函数接口可以通过Lambda表达式实现
Java函数接口可以通过Java Lambda Expression实现。这是一个示例,该示例实现了此Java函数接口教程的开头定义的函数接口MyFunctionalInterface:
MyFunctionalInterface lambda = () -> { System.out.println("Executing..."); }
Java lambda表达式从Java接口实现单个方法。为了知道lambda表达式实现的方法,该接口只能包含一个未实现的方法。换句话说,该接口必须是Java函数接口。
我将不更详细地解释Java lambda表达式。单击本节开头的链接以了解有关lambda表达式的更多信息。
Java内置函数接口
Java包含一组针对常见用例设计的函数接口,因此我们不必为每个小用例创建自己的函数接口。在以下各节中,我将描述Java中的一些内置函数接口。
函数
Java Function接口(java.util.function.Function)是Java中最主要的函数接口之一。 " Function"接口表示一个函数(方法),该函数采用单个参数并返回单个值。以下是"函数"接口定义的外观:
public interface Function<T,R> { public <R> apply(T parameter); }
除了上面列出的方法外,"函数"接口实际上还包含一些其他方法,但是由于它们都带有默认实现,因此我们不必实现这些额外方法。额外的方法将在后面的部分中说明。
要实现"函数"接口,唯一需要实现的方法就是" apply()"方法。这是一个"函数"的实现示例:
public class AddThree implements Function<Long, Long> { @Override public Long apply(Long aLong) { return aLong + 3; } }
这个Function
实现实现了apply()
方法,因此它以Long
作为参数,并返回一个'Long'。这是一个使用上面的AddThree
类的例子:
Function<Long, Long> adder = new AddThree(); Long result = adder.apply((long) 4); System.out.println("result = " + result);
首先,此示例创建一个新的AddThree
实例并将其分配给Function
变量。第二,该示例在AddThree
实例上调用apply()
方法。第三,该示例打印出结果(为7)。
我们还可以使用Java Lambda表达式实现"函数"接口。看起来是这样的:
Function<Long, Long> adder = (value) -> value + 3; Long resultLambda = adder.apply((long) 8); System.out.println("resultLambda = " + resultLambda);
如我们所见,"函数"接口的实现现在内联在" adderLambda"变量的声明中,而不是在单独的类中。这有点短,而且我们可以在上面的代码中直接看到它在做什么。
Predicate
Java Predicate接口java.util.function.Predicate代表一个简单函数,该函数以单个值作为参数,并返回true或者false。这是Predicate
函数接口定义的外观:
public interface Predicate { boolean test(T t); }
"Predicate"接口比" test()"方法包含更多的方法,但是其余方法是默认方法或者静态方法,我们不必实现这些方法。
我们可以使用一个类来实现Predicate
接口,如下所示:
public class CheckForNull implements Predicate { @Override public boolean test(Object o) { return o != null; } }
我们还可以使用Lambda表达式实现JavaPredicate
接口。这是一个使用Java lambda表达式实现Predicate
接口的示例:
Predicate predicate = (value) -> value != null;
Predicate接口的lambda实现实际上与上述使用类的实现相同。
一元运算符UnaryOperator
Java" UnaryOperator"接口是一个函数接口,表示一个操作,该操作采用单个参数并返回相同类型的参数。这是一个JavaUnaryOperator
实现的示例:
UnaryOperator<Person> unaryOperator = (person) -> { person.name = "New Name"; return person; };
" UnaryOperator"接口可用于表示将特定对象作为参数,修改该对象并可能作为函数流处理链的一部分再次返回的操作。
二进制运算符BinaryOperator
Java" BinaryOperator"接口是一个函数接口,表示一个具有两个参数并返回单个值的操作。参数和返回类型必须是相同的类型。
JavaBinaryOperator
接口在实现对两个相同类型的元素求和,相减,除法,相乘等函数并返回相同类型的第三个元素时非常有用。
这是BinaryOperator
接口的示例实现:
BinaryOperator<MyValue> binaryOperator = (value1, value2) -> { value1.add(value2); return value1; };
提供者Supplier
JavaSupplier
接口是一个函数接口,表示提供某种值的函数。供应商界面也可以被认为是工厂界面。这是JavaSupplier
接口的示例实现:
Supplier<Integer> supplier = () -> new Integer((int) (Math.random() * 1000D));
这个JavaSupplier
实现返回一个新的Integer
实例,其随机值在0到1000之间。
消费者Consumer
JavaConsumer
接口是一个函数接口,表示使用一个值而不返回任何值的函数。 JavaConsumer
实现可以打印出一个值,或者将其写入文件中,或者通过网络等。这是JavaConsumer
接口的示例实现:
Consumer<Integer> consumer = (value) -> System.out.println(value);
这个JavaConsumer
实现将作为参数传递给它的值输出到System.out
中。