Java8——Lambda表达式
语法糖指的是使用更方便,但原理不变的代码语法
lambda表达式
java8有一个词汇不得不提,就是 函数式接口
函数式接口:有且只有一个抽象方法的接口,我们可以在接口上标注@FunctionalInterface,表示是一个函数式接口,主要作为参数或者返回值使用1
2
3
4
5
6
7package cn.itcast.helloworld.java8;
public interface MyFunc {
public abstract void save();
}
lambda表达式的重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
注:借鉴菜鸟教程,感觉总结特别好
接下来展示一个小demo1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public static void save(MyFunc myFunc){
myFunc.save();
}
public static void main(String[] args) {
//传递接口的匿名内部类
save(new MyFunc() {
public void save() {
System.out.println("执行完成");
}
});
//由于方法的参数是一个函数式接口,所以可以使用lambda表达式
save(()->{
System.out.println("lambda表达式的使用");
});
//由于函数式接口的方法没有参数,而且只有一条执行语句
save(()->System.out.println("lambda表达式的使用"));
}
lambda表达式是延迟执行,可以对代码执行结果不急用用lambda语法,有助于提高性能
lambda执行的前提是必须有函数式接口
我们做了一个demo最适合解释lambda表达式的用法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/*
* 我们做了这么一个案例:
* 当level的值为1的时候,打印日志,
* 其他都不打印,为了防止我们苦费心思拿到日志之后,结果level不为 1,就损耗了性能
* 所以我们使用有延迟加载作用的lambda
*
* */
public class Demo {
public static void save(int level,MyFunc myFunc){
if(level == 1) myFunc.printLog();
}
//只有level的数字是1的时候,lambda表达式才会执行
public static void main(String[] args) {
save(1,()-> System.out.println("这是日志"));
}
}
Java中也给我们提供弄了很多函数式接口
Comparator比较型接口
在java中,Comparator接口是个函数式接口,内部只有一个抽象方法,所以按照lambda表达式规则,可以这样写1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class MyCompare {
public static Comparator<String> myComparator(){
//匿名内部类
// return new Comparator<String>() {
// @Override
// public int compare(String o1, String o2) {
// return o2.length()-o1.length();
// }
// };
//采用Lambda表达式
return (o1,o2)->o2.length()-o1.length();
}
public static void main(String[] args) {
String[] arrList = {"aaaaa","b","cccc","dddd"};
System.out.println("原先顺序:"+Arrays.toString(arrList));
Arrays.sort(arrList,myComparator());
System.out.println("现在顺序:"+Arrays.toString(arrList));
}
}
生产型接口指的是接口的泛型是什么类型,那么接口最后的返回值就是什么类型
Supplier生产型接口
1 | import java.util.function.Supplier; |
Consumer消费型接口
消费型接口,指的是泛型执行什么类型,就可以消费什么类型的数据1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import java.util.function.Consumer;
public class ConsumerInterface {
public static void myConsumer(String name, Consumer<String> consumer){
consumer.accept(name);
}
public static void main(String[] args) {
//我们实现翻转输出
myConsumer("李茂展",(name)->{
String nameReverse = new StringBuffer(name).reverse().toString();
System.out.println(nameReverse);
});
}
}
Consumer中有一个默认方法andThen,我们可以这样使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import java.util.function.Consumer;
public class ConsumerInterface {
public static void myConsumer(String name, Consumer<String> consumer1, Consumer<String> consumer2){
//谁写在前面谁先消费
consumer1.andThen(consumer2).accept(name);
}
public static void main(String[] args) {
//我们实现先大写后小写输出
myConsumer("Tom",(name)-> System.out.println(name.toUpperCase()),(name)->
System.out.println(name.toLowerCase()));
}
}
Predicate判断型接口
predicate是用于判断的函数式接口,内部有一个test抽象方法,返回值是bool类型1
2
3
4
5
6
7
8
9
10
11
12
13
14import java.util.function.Predicate;
public class PredicateInterface {
public static boolean myPredicate(String str, Predicate<String> predicate){
return predicate.test(str);
}
public static void main(String[] args) {
String str = "abcdefg";
boolean bool = myPredicate(str, (str1) -> str1.length() > 5);
System.out.println(bool);
}
}
predicate有三个默认方法:
- and: 表示条件同时满足
1 | import java.util.function.Predicate; |
- or: 表示条件只需要满足一个就可以返回true
和上面的代码差不多相同,区别就是把上面的and替换成or,return predicate1.or(predicate2).test(str);
- negate: 表示取反
1 | import java.util.function.Predicate; |
Function转换型接口
Function中最主要的抽象方法是apply(T,t),T表示转换前的类型,t表示转换后的类型1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import java.util.function.Function;
public class MyFunction {
public static void myFunc(String str, Function<String,Integer> function){
Integer val = function.apply(str);
System.out.println(val);
}
public static void main(String[] args) {
//使用lambda表达式把字符串 "123"输出为数字 123
myFunc("123",(str)->Integer.parseInt(str));
}
}
Function有个默认方法andThen1
2
3
4
5
6
7
8
9
10
11
12
13public class MyFunction {
public static void myFunc(String str, Function<String,Integer> function1,Function<Integer,String> function2){
String str_val = function1.andThen(function2).apply(str);
System.out.println(str_val);
}
public static void main(String[] args) {
//使用lambda表达式把字符串转成数字然后再加上10再转换为字符串
myFunc("123",(str)->Integer.parseInt(str),(val)->String.valueOf(val +=10));
}
}