一、说明
Jdk1.8最重要的特性即Lambda表达式。它允许把一个函数作为参数传递进方法中,简化了匿名实现类的书写
Lambda 表达式需要 函数式接口 的支持,即把只有一个抽象方法的接口的匿名实现,以方法参数在左,方法实现在右的形式构建,并将其作为参数传进方法中
Lambda表达式引入了一个新的操作符 "->",它将Lambda分为两个部分:
/**
* 左侧:指定了Lambda表达式所需要的所有参数
* 右侧:指定了Lambda表达式所要执行的代码块
*/
(参数类型 参数名, 参数类型 参数名...) -> {
代码块,即方法体
};
二、示例
- 1、线程
// SE8 之前
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println("hello world");
}
});
thread.start();
// SE8 开始
Runnable runnable = () -> System.out.println("run ...");
Thread thread = new Thread(runnable);
thread.start();
// SE8 简写
new Thread(() -> System.out.println("run ...")).start();
- 2、排序
List<String> strs = new ArrayList<String>();
// SE8 之前
Collections.sort(strs, new Comparator<String>() {
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
});
// SE8 开始
Collections.sort(strs, (str1, str2) -> str1.compareTo(str2));
- 3、自定义
@FunctionalInterface
public interface ExecInterface {
public void execute(String a, String b);
}
// SE8之前
ExecInterface execOri = new ExecInterface() {
@Override
public void execute(String a, String b) {
System.out.println(a + b);
}
};
execOri.execute("aaaa", "bbbb");
// SE8开始
ExecInterface execLam = (a, b) -> System.out.println(a + b);
execLam.execute("aaaa", "bbbb");
三、语法
- 1、完整语法
// 函数式接口方法
public void execute(String a, String b);
// Lambda表达式
ExecInterface execLam = (String a, String b) -> {System.out.println(a + b);};
- 2、参数类型可以省略 (类型推断:因为接口中只有一个抽象方法,知道方法即可推出参数及其类型)
// 函数式接口方法
public void execute(String a, String b);
// Lambda表达式
ExecInterface execLam = ( a, b) -> {System.out.println(a + b);};
- 3、当参数个数只有一个时,也可以省略()
//函数式接口方法
public void execute(String a);
//Lambda表达式
ExecInterface execLam = a -> { System.out.println(a); };
- 4、当方法体中只有一行代码时,可以省略{}
//函数式接口方法
public void execute(String a);
//Lambda表达式
ExecInterface execLam = a -> System.out.println(a);
- 5、当方法体中只有一行代码并且需要返回值时,也可以省略掉return
// 函数式接口方法
public String execute(String a);
// Lambda表达式
ExecInterface execLam = a -> a + "hello";
- 6、当表达式没有参数时,一对小括号是不能省略掉的
// 函数式接口方法
public void execute();
// Lambda表达式
ExecInterface execLam = () -> System.out.println("Hello");
四、常用
Java8 内置了大量函数式接口,位于java.util.function包中,通常情况下不需要再自定义接口
- 1、Supplier<T> :供应商;没有参数,有返回值
Supplier<String> supplier = () -> "Hello!";
System.out.println(supplier.get());
- 2、Consumer<T> :消费者;只有一个参数,没有返回值
Consumer<String> consumer = (name) -> System.out.println(name + ": " + "Hello!");
consumer.accept("Xlien");
- 3、Function<T, R> :函数;一个参数,一个返回值
Function<String, String> func = (name) -> name + ": " + "Hello!";
System.out.println(func.apply("Xlien"));
- 4、BiFunction<T, U, R> :二元函数;两个参数,一个返回值
BiFunction<String, String, String> biFunc = (String name, String msg) -> {
String str = name + "," + msg + "!";
return str;
};
System.out.println(biFunc.apply("Xlien", "Hello!"));
- 5、Comparator<T> :比较器;接收两个参数,返回比较的结果
Comparator<String> comparator = (s1, s2) -> s1.compareTo(s2);
System.out.println(comparator.compare("abc", "abd"));
- 6、Predicate<T> :断言;用于测试一个条件的真假
Predicate<String> predicate = (str) -> str.length() < 20;
// 即
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String str) {
return str.length() < 20;
}
};
System.out.println(predicate.test("xilen@gmail.com")); // 判断真假
System.out.println(predicate.negate().test("xilen@gmail.com")); // 逻辑否的判断真假
System.out.println(predicate.and((str) -> str.length() > 10).test("abcdefg")); // 组合判断 length<20 AND length > 10
System.out.println(Predicate.isEqual("aaaa").test("aaaa")); // 判断是否相等(equal)