共计 4920 个字符,预计需要花费 13 分钟才能阅读完成。
上一篇小乐带大家学过 Java8 新特性 -Lambda 表达式,什么时候可以使用 Lambda?通常 Lambda 表达式是用在函数式接口上使用的。从 Java8 开始引入了函数式接口,其说明比较简单: 函数式接口 (Functional Interface) 就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。java8 引入 @FunctionalInterface 注解声明该接口是一个函数式接口。
1、语法定义
/**
* 定义函数式接口
* 接口上标注 @FunctionalInterface 注解
*/
@FunctionalInterface
public interface ICollectionService {
/**
* 定义打印方法
*/
void print();
}
在 Java8 以前,已有大量函数式接口形式的接口(接口中只存在一个抽象方法),只是没有强制声明。例如:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
Java8 新增加的函数接口在 java.util.function 包下,它包含了很多类,用来支持 Java 的 函数式编程,该包中的函数式接口有:
序号 接口 & 描述 1 BiConsumer<T,U> 代表了一个接受两个输入参数的操作,并且不返回任何结果 2 BiFunction<T,U,R> 代表了一个接受两个输入参数的方法,并且返回一个结果 3 BinaryOperator<T> 代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果 4 BiPredicate<T,U> 代表了一个两个参数的 boolean 值方法 5 BooleanSupplier 代表了 boolean 值结果的提供方 6 Consumer<T> 代表了接受一个输入参数并且无返回的操作 7 DoubleBinaryOperator 代表了作用于两个 double 值操作符的操作,并且返回了一个 double 值的结果。8 DoubleConsumer 代表一个接受 double 值参数的操作,并且不返回结果。9 DoubleFunction<R> 代表接受一个 double 值参数的方法,并且返回结果 10 DoublePredicate 代表一个拥有 double 值参数的 boolean 值方法 11 DoubleSupplier 代表一个 double 值结构的提供方 12 DoubleToIntFunction 接受一个 double 类型输入,返回一个 int 类型结果。13 DoubleToLongFunction 接受一个 double 类型输入,返回一个 long 类型结果 14 DoubleUnaryOperator 接受一个参数同为类型 double, 返回值类型也为 double。15 Function<T,R> 接受一个输入参数,返回一个结果。16 IntBinaryOperator 接受两个参数同为类型 int, 返回值类型也为 int。17 IntConsumer 接受一个 int 类型的输入参数,无返回值。18 IntFunction<R> 接受一个 int 类型输入参数,返回一个结果。19 IntPredicate:接受一个 int 输入参数,返回一个布尔值的结果。20 IntSupplier 无参数,返回一个 int 类型结果。21 IntToDoubleFunction 接受一个 int 类型输入,返回一个 double 类型结果。22 IntToLongFunction 接受一个 int 类型输入,返回一个 long 类型结果。23 IntUnaryOperator 接受一个参数同为类型 int, 返回值类型也为 int。24 LongBinaryOperator 接受两个参数同为类型 long, 返回值类型也为 long。25 LongConsumer 接受一个 long 类型的输入参数,无返回值。26 LongFunction<R> 接受一个 long 类型输入参数,返回一个结果。27 LongPredicateR 接受一个 long 输入参数,返回一个布尔值类型结果。28 LongSupplier 无参数,返回一个结果 long 类型的值。29 LongToDoubleFunction 接受一个 long 类型输入,返回一个 double 类型结果。30 LongToIntFunction 接受一个 long 类型输入,返回一个 int 类型结果。31 LongUnaryOperator 接受一个参数同为类型 long, 返回值类型也为 long。32 ObjDoubleConsumer<T> 接受一个 object 类型和一个 double 类型的输入参数,无返回值。33 ObjIntConsumer<T> 接受一个 object 类型和一个 int 类型的输入参数,无返回值。34 ObjLongConsumer<T> 接受一个 object 类型和一个 long 类型的输入参数,无返回值。35 Predicate<T> 接受一个输入参数,返回一个布尔值结果。36 Supplier<T> 无参数,返回一个结果。37 ToDoubleBiFunction<T,U> 接受两个输入参数,返回一个 double 类型结果 38 ToDoubleFunction<T> 接受一个输入参数,返回一个 double 类型结果 39 ToIntBiFunction<T,U> 接受两个输入参数,返回一个 int 类型结果。40 ToIntFunction<T> 接受一个输入参数,返回一个 int 类型结果。41 ToLongBiFunction<T,U> 接受两个输入参数,返回一个 long 类型结果。42 ToLongFunction<T> 接受一个输入参数,返回一个 long 类型结果。43 UnaryOperator<T> 接受一个参数为类型 T, 返回值类型也为 T。
对于 Java8 中提供的这么多函数式接口,开发中常用的函数式接口有以下几个
Predicate,Consumer,Function,Supplier。
2、函数式接口实例
2.1、Predicate
java.util.function.Predicate<T> 接口定义了一个名叫 test 的抽象方法,它接受泛型 T 对象,并返回一个 boolean 值。在对类型 T 进行断言判断时,可以使用这个接口。通常称为断言性接口。
使用 Predicate 接口实现字符串判空操作
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
…
}
public static void main(String[] args) {
/**
* 借助 Lambda 表达式实现 Predicate test 方法
*/
Predicate<String> p01=(str)->str.isEmpty()||str.trim().isEmpty();
/**
* 测试传入的字符串是否为空
*/
System.out.println(p01.test(“”));
System.out.println(p01.test(” “));
System.out.println(p01.test(“admin”));
}
测试代码
public static void main(String[] args) {
/**
* 借助 Lambda 表达式实现 Predicate test 方法
*/
Predicate<String> p01=(str)->str.isEmpty()||str.trim().isEmpty();
/**
* 测试传入的字符串是否为空
*/
System.out.println(p01.test(“”));
System.out.println(p01.test(” “));
System.out.println(p01.test(“admin”));
}
测试结果:
2.2、Consumer
java.util.function.Consumer<T> 接口定义了一个名叫 accept 的抽象方法,它接受泛型 T,没有返回值(void)。如果需要访问类型 T 的对象,并对其执行某些操作,可以使用这个接口,通常称为消费性接口。
使用 Consumer 实现集合遍历操作
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
…
}
/**
* 借助 Lambda 表达式实现 Consumer accept 方法
*/
Consumer<Collection> c01 = (collection) -> {
if (null != collection && collection.size() > 0) {
for (Object c : collection) {
System.out.println(c);
}
}
};
List<String> list = new ArrayList<String>();
list.add(“ 诸葛亮 ”);
list.add(“ 曹操 ”);
list.add(“ 关羽 ”);
// 遍历 list 输出元素内容到控制台
c01.accept(list);
2.3、Function
java.util.function.Function<T, R> 接口定义了一个叫作 apply 的方法,它接受一个泛型 T 的对象,并返回一个泛型 R 的对象。如果需要定义一个 Lambda,将输入的信息映射到输出,可以使用这个接口(比如提取苹果的重量,或把字符串映射为它的长度), 通常称为功能性接口。
使用 Function 实现用户密码 Base64 加密操作
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
// 实现用户密码 Base64 加密操作
Function<String,String> f01=(password)->Base64.getEncoder().encodeToString(password.getBytes());
// 输出加密后的字符串
System.out.println(f01.apply(“123456”));
加密后结果如下:
2.4、Supplier
java.util.function.Supplier<T> 接口定义了一个 get 的抽象方法,它没有参数,返回一个泛型 T 的对象,这类似于一个工厂方法, 通常称为功能性接口。
使用 Supplier 实现 SessionFactory 创建
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
/**
* 产生一个 session 工厂对象
*/
Supplier<SessionFactory> s = () -> {
return new SessionFactory();
};
s.get().info();
以上就是小乐带给大家的 Java8 新特性之函数式接口,下一篇将会为大家带来 Java8 新特性之方法引用,敬请关注。
转载请注明文章出处和作者,谢谢合作!