函数式接口中使用lambda表达式
函数式接口:只有一个抽象方法(Object类中的方法除外)的接口,用@FunctionalInterface注解进行修饰。
@FunctionalInterface
public interface UserMapper {
int delete();
default int insert() {
return 1;
};
static int update() {
return 1;
};
}
//default 、static 、Object类中的方法除外,含有一个抽象方法的接口。
在1.8之前我们熟悉的函数式接口有Runnable、Callable<T>、Comparator<T>等等
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
1.8之后的函数式接口(java.util.function包下大部分为函数式接口)
Supplier(代表一个输出)
Consumer(代表一个输入)
BiConsumer(代表两个输入)
Function(代表一个输入一个输出:输入输出一般是不同类型)
UnaryOperator(代表一个输入一个输出:输入输出一般是相同类型)
BiFunction(代表两个输入一个输出:输入输出一般是不同类型)
BinaryOperator(代表两个输入一个输出:输入输出一般是相同类型)
lambda表达式语法结构
LanbdaParameter -> LanbadaBody
lambda表达式是可以有参数的,当参数个数是一个时,括号可以省略。
无参数格式
()-> expr
单参数
(par)-> expr
或
par -> expr
多参数
(Object ...args) -> expr
当表达式中逻辑比较多时,需要加大括号,如果逻辑简单,大括号和return可以省略。
特点、注意项
特点:lambda表达式可以自动推断出参数类型
注意项:
- lambda表达式不允许使用final类型的参数。
- lambda表达式不允许使用在非函数式接口中。
- 函数式接口被实现时,static或final方法可能会有返回值,函数式接口中的抽象方法也可能有返回值。当函数式接口抽象方法返回值是void类型时,匿名内部类可以调用static或final方法。当抽象方法有返回值时,只能调用相同返回值类型的static或final方法。
package com.per.lambada;
@FunctionalInterface
interface UserMapper {
void insert(User u) ;
}
class User{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Main{
public static void main(String[] args) throws Exception {
// 匿名内部类
UserMapper us =new UserMapper() {
@Override
public void insert(User u) {
// TODO Auto-generated method stub
System.out.println("insert user"+u);
}
};
// lambda表达式
UserMapper u1 = (User u)->System.out.println("insert user"+u);
u1.insert(new User());
us.insert(new User());
}
}
insert usercom.per.lambada.User@548c4f57
insert usercom.per.lambada.User@1218025c
UserMapper是一个接口,虽然有new,但实际上是创建了一个匿名内部类。new得到匿名内部类的对象再向上转型从而实现了UserMapper接口。
复杂的lambda
实现从1累积到10的和
public static void main(String[] args) throws Exception {
Function<Integer,Integer> f = a ->{
int sum =0;
for(int i=0;i<=a;i++) {
sum +=i;
}
return sum;
};
System.out.println(f.apply(10));
}
lambda表达式生成函数式接口实例
简单样例
public static void main(String[] args) {
// 无参无返回值
Runnable r = ()->{};
Closeable c = ()->{};
// 有参无返回值
Consumer<String> c2 = a -> {};
// 无参有返回值
Supplier<String> s1 = () -> "hhaa";
// 有参有返回值
Function<String,Integer> f = str -> str.toUpperCase();
}
网友评论