前言
最近遇到 Java8 里的函数式接口,记录一下常规使用。
实现
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 Lambda
表达式。
Java8 里的函数式接口可分为五大类:
- 消费型接口(Consumer):接口用于接收参数,但是没有返回值;
- 供给型接口(Supplier):接口用于提供数据,但是没有接收参数;
- 断言型接口(Predicate):接口用于判断数据是否符合某种规则;
- 函数型接口(Function):接口用于将数据转换为另一种数据;
- 运算型接口(Operator):接口用于对数据进行运算。
五大类接口
消费型接口(Consumer)
用法:
- 消费型接口(Consumer),接口用于接收参数,但是没有返回值。
出入参:
- 入参类型:
T
- 返回类型:
void
接口方法:
void accept(T t);
供给型接口(Supplier)
用法:
- 供给型接口(Supplier),接口用于提供数据,但是没有接收参数。
出入参:
- 入参类型:无
- 返回类型:
T
接口方法:
T get();
断言型接口(Predicate)
用法:
- 断言型接口(Predicate),接口用于判断数据是否符合某种规则。
出入参:
- 入参类型:
T
- 返回类型:
boolean
接口方法:
boolean test(T t);
函数型接口(Function)
用法:
- 函数型接口(Function),接口用于将数据转换为另一种数据。
出入参:
- 入参类型:
T
- 返回类型:
R
接口方法:
R apply(T t);
运算型接口(Operator)
用法:
- 运算型接口(Operator),接口用于对数据进行运算。
出入参:
- 入参类型:
T
- 返回类型:
T
接口方法:
T apply(T t);
更多的信息可查看菜鸟教程。
代码示例
package demo;
import java.util.function.*;
/**
* @author 郎家岭伯爵
* @time 2025年3月11日11:03:39
*/
public class Demo {
public static void main(String[] args) throws Exception {
testFunctionInterface();
testFunctionInterface2();
testFunctionInterface3();
testFunctionInterface4();
testFunctionInterface5();
}
/**
* 测试函数式接口:消费型接口(Consumer),接口用于接收参数,但是没有返回值。
* 消费型接口:
* 入参类型:T
* 返回类型:void
* Consumer<T> 消费型接口
* void accept(T t);
*/
private static void testFunctionInterface() {
Consumer<String> consumer = new Consumer<>() {
@Override
public void accept(String s) {
System.out.println("accept: " + s);
}
};
consumer.accept("Hello,World!");
/**
* Consumer接口的子接口:
* LongConsumer:接收一个long类型的参数,没有返回值。
* 其它子接口:IntConsumer、DoubleConsumer。
* 其它四种类型的函数式接口均有相似用法,这里仅以LongConsumer为例,其它不再赘述。
*/
new LongConsumer() {
@Override
public void accept(long value) {
System.out.println("accept: " + value);
}
}.accept(100L);
}
/**
* 测试函数式接口:供给型接口(Supplier),接口用于提供数据,但是没有接收参数。
* 供给型接口:
* 入参类型:无
* 返回类型:T
* Supplier<T> 供给型接口
* T get();
*/
private static void testFunctionInterface2() {
Supplier<String> supplier = new Supplier<>() {
@Override
public String get() {
return "Hello,World!";
}
};
System.out.println(supplier.get());
/**
* 这里提供一种更简洁的写法,使用Lambda表达式。其它函数式接口也可以使用Lambda表达式,这里不再赘述。
*/
long asLong = ((LongSupplier) () -> 100L).getAsLong();
System.out.println(asLong);
}
/**
* 测试函数式接口:断言型接口(Predicate),接口用于判断数据是否符合某种规则。
* 断言型接口:
* 入参类型:T
* 返回类型:boolean
* Predicate<T> 断言型接口
* boolean test(T t);
*/
private static void testFunctionInterface3() {
Predicate<String> predicate = new Predicate<>() {
@Override
public boolean test(String s) {
return s.isEmpty();
}
};
System.out.println(predicate.test("Hello,World!"));
}
/**
* 测试函数式接口:函数型接口(Function),接口用于将数据转换为另一种数据。
* 函数型接口:
* 入参类型:T
* 返回类型:R
* Function<T, R> 函数型接口
* R apply(T t);
*/
private static void testFunctionInterface4() {
Function<String, Integer> function = new Function<>() {
@Override
public Integer apply(String s) {
return s.length();
}
};
System.out.println(function.apply("Hello,World!"));
}
/**
* 测试函数式接口:运算型接口(Operator),接口用于对数据进行运算。
* 运算型接口:
* 入参类型:T
* 返回类型:T
* UnaryOperator<T> 运算型接口
* T apply(T t);
*/
private static void testFunctionInterface5() {
UnaryOperator<String> unaryOperator = new UnaryOperator<>() {
@Override
public String apply(String s) {
return s + "!";
}
};
System.out.println(unaryOperator.apply("Hello,World"));
}
}
自定义函数式接口
如何自定义一个函数式接口呢?
写一个接口类,在类上添加 @FunctionalInterface
即可。但要注意接口类里有且只能有一个方法(函数式接口的定义)。
自定义一个函数式接口类
package functioninterfacedemo;
/**
* @author 郎家岭伯爵
* @time 2025年3月11日11:17:00
* @version 1.0
* @description 自定义函数式接口。
*/
@FunctionalInterface
public interface GreetServer {
/**
* 打招呼的方法。
* @param name 要打招呼的人的名字。
*/
void greet(String name);
}
使用自定义函数式接口
package functioninterfacedemo;
/**
* @author 郎家岭伯爵
* @time 2025年3月11日11:19:17
* @version 1.0
* @description 测试自定义函数式接口。
*/
public class Demo {
public static void main(String[] args) {
testGreetServer();
}
public static void testGreetServer() {
GreetServer greetServer = new GreetServer() {
@Override
public void greet(String name) {
System.out.println("Hello, " + name + "!");
}
};
greetServer.greet("郎家岭伯爵");
}
}
测试使用
执行以上代码后输出:
Hello, 郎家岭伯爵!
完成自定义函数式接口的使用!
总结
总结下 Java8 中的函数式接口的使用。