Lambda表达式
基本概念
一、表达式形式:
-
参数,箭头,一个表达式
(String first,String second) ->first.length()-second.length()
-
参数,箭头,{多个语句}
(first,second)-> { //形参不写类型 可以从上下文推断出来 int result = (-1) * (first.length()-second.length()); return result; }
-
无参数,仅保留括号,箭头,表达式
new Thread( ()-> { int sum=0; for(int i=0;i<100;i++){ sum = sum + i; } System.out.println("总和:" + sum); } ).start();
-
一个参数,可省略括号,箭头,表达式
public interface Adder { public int selfAdd(int x); } //Lambda表达式实现上面的接口 Adder c1 = x-> { x++; };
二、特点:
- 类似于匿名方法,一个没有名字的方法
- 参数,箭头,表达式语句
- 可以忽略写参数类型(类型可以推断出来)
- 坚决不声明返回值类型(类型可以推断出来)
- 没有public/protected/private/static/final等修饰符
- 单据表达式,将直接返回值,不用大括号
- 带return语句,算多句,必须用大括号
函数式接口
一、示例:
首先,举一个示例:
Lambda表达式
Comparable<String> c = (String first,String second) ->
first.length() - second.length();
匿名内部类
Comparator<String> c = new Comparator<String>() {
public int compare(String first,String second)
{
return first.length() - second.length();
}
};
从上面可以看出,上面的表达式,没名字有实现,下面的匿名内部类有名字没实现,前者更加简洁高效且不会产生额外的class文件,Lambda表达式(匿名函数)就会自动成为接口方法的实现
二、函数式接口的特点:
- 是一个接口,符合Java接口的定义
- 只包含一个抽象方法的接口
- 可以包括其他的default方法、static方法、private方法
- 由于另一个未实现的方法,所以Lambda表达式可以自动填充上这个尚未实现的方法
- 采用Lambda表达式,可以自动创建一个(伪)嵌套类的对象(没有实际的嵌套类class文件产生),然后使用,比真正嵌套类更加轻量,更加简洁高效
三、自定义函数式接口:
接口:
@FunctionalInterface //用于标记函数式接口的注解,用于编译器检查
public interface NumberChecker {
public boolean checkNumber(int a); //假设用于判断是否为偶数
}
测试类:
public class TestDemo {
public static void main(String[] args) {
NumberChecker nc = s -> //定义NumberChecker对象
{
if(s%2==0)
return true;
return false;
};
System.out.println(nc.checkNumber(4));
System.out.println(nc.checkNumber(5));
}
}
结果:
true
false
四、系统自带的函数式接口
接口名称 | 参数 | 返回值 | 示例 |
---|---|---|---|
Predicate<T> | T | Boolen | 接受一个参数, 返回一个布尔值 |
Consumer<T> | T | void | 接受一个参数, 无返回值 |
Function<T,R> | T | R | 接收一个参数, 返回一个值 |
Supplier<T> | None | T | 数据工厂,对外提供一个数据 |
代码示例:
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import static java.lang.StrictMath.floor;
import static java.lang.StrictMath.random;
public class Demo {
public static void main(String[] args) {
//Predicate<T>谓词接口
Predicate<String> oddLength = s -> {
//判断字符串长度是否为偶数
if (s.length()%2 == 0)
return true;
return false;
};
//测试
System.out.println(oddLength.test("aaaaa"));
//Consumer<T>消费者接口,无返回值
Consumer<String> printer = s -> {
System.out.println(s);
};
//测试
printer.accept("aaaaa");
//Supplier<T>数据工厂;
String[] strings = {"aa","bb","cc","dd","ee","ff","gg","hh","ii","jj"};
Supplier<String> StringFactory = () ->
strings[(int) floor(random()*10)]; //随机返回数据中的一个值
//测试
for (int i=0;i<5;i++){
System.out.println(StringFactory.get());
}
//Function<T,R>功能接口
Function<String,String> upper = s -> {
//可以做更复杂的操作
return s.toUpperCase(); //此处仅演示一个简单的将小写变大写
};
//测试
for (String s : strings){
System.out.println(upper.apply(s));
}
}
}