四种方式
定义
/**
定义函数接口
- 必须只有一个强制实现的方法
- 使用 @FunctionalInterface 标记该接口, 以在编译期检查是否有错误
- 可以有一个或多个默认方法
@FunctionalInterface
public interface ICalculator {
int square(int i);
}
一个参数
一个参数的时候不需要使用()
@Test
public void test() {
ICalculator ic = i -> i * i;
int res = ic.square(2);
System.out.println(res);
}
多个参数
多个参数时需要使用()
@Test
public void test2() {
IAddCalculator add = (a, b) -> a + b;
int res = add.add(1, 2);
System.out.println(res);
}
需要参数类型
有时需要指定参数类型,需要使用()
@Test
public void test3() {
IAddCalculator ia = (int a, int b) -> a + b;
int res = ia.add(1, 2);
System.out.println(res);
}
多行
当代码不止一行时,需要使用{}
@Test
public void test4() {
IAddCalculator ia = (a, b) -> {
int c = a + b;
return c + a + b;
};
int res = ia.add(1, 2);
System.out.println(res);
}
函数接口
自己定义
现在有如下代码, 一个函数接口, 已经一个使用改函数接口的类User
@FunctionalInterface
public interface SayHello {
String sayHi(String username);
}
public class User {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String sayHello(SayHello sayHello) {
return sayHello.sayHi(this.username);
}
}
测试代码如下
@org.junit.Test
public void test() {
User user = new User();
user.setUsername("lisi");
String hi = user.sayHello(username -> "hello " + username);
System.out.println(hi);
}
内置函数接口
上面的代码,核心代码是user.sayHello(username -> "hello " + username);
。而为了这一行代码创建一个函数接口有点多此一举。
为了处理这种情况, JDK8提供了函数接口,可以帮我们简化上面的代码
public class Person {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String sayHello(Function<String,String> sayHello){
return sayHello.apply(username);
}
}
@org.junit.Test
public void test2() {
Person zs = new Person();
zs.setUsername("zhang san");
String s = zs.sayHello(username -> "你好 " + username);
System.out.println(s);
}
Person 中的sayHello方法使用了一个Function<String,String>来替代我们自己的函数接口。第一个泛型参数表示输入的参数类型,第二个泛型参数表示输出的参数类型。
其他内置
接口 输入参数 返回类型 说明
UnaryOperator T T 一元函数,输入输出类型相同
Predicate T boolean 断言
Consumer T / 消费一个数据,只有输入没有输出
Function<T,R> T R 输入 T 返回 R,有输入也有输出
Supplier / T 提供一个数据,没有输入只有输出
BiFunction<T,U,R> (T,U) R 两个输入参数
BiPredicate<L, R> (L,R) boolean 两个输入参数
BiConsumer<T, U> (T,U) void 两个输入参数
BinaryOperator (T,T) T 二元函数,输入输出类型相同
方法引用
是什么
方法引用时lambda的一个表达式, 操作符是::
静态引用
当函数接口中只是调用一个静态方法时,采用方法调用的方式可以简化代码
@Test
public void test() {
Function<Integer, String> convert = String::valueOf;
String res = convert.apply(new Integer(1234));
System.out.println(res);
}
@Test
public void test2() {
Consumer<Integer> consumer = System.out::println;
consumer.accept(new Integer("2234"));
}