代码总是朝着简洁清爽的方向发展,Lambda表达式是个很好的示例
另外还有Lombox
Lambda表达式的使用:
public class Test2 {
/*注意这几个接口和类,因为待会他们大有作为*/
interface Math {
long sum(int a,int b) throws RuntimeException;
}
static class LambdaDemo{
static long sum1(int a, int b){
return a+b;
}
int sum2(int a,int b){
return a+b;
}
}
interface LambdaDemoBuilder{
LambdaDemo getLambdaDemo();
}
@Test
void test2() throws ExecutionException, InterruptedException {
/*通常使用匿名实现类的方式*/
Math math = new Math() {
@Override
public long sum(int a, int b) {
return (long) a+b;
}
};
System.out.println(math.sum(123,123));
/*使用Lambda表达式会使代码更加清爽
* (参数...) -> 表达式或者过程
* */
Math math1 = (int a,int b) -> (long) a+b;
/*参数类型可以省略
如果参数列表只有一个,()也可以省略
如果方法的重写需要多行代码,放在{}即可*/
Math math2 = (a,b) -> {
long sum = (long) a+b;
return sum;
};
/*实际应用
* 开启一个线程,将Runnable匿名实例当做参数传递
* 重写run方法,打印10条Lambda
* */
new Thread(() -> {
for (byte b : new byte[10]){
System.out.println("Lambda");
}
}).start();
/*Callable
* 你瞧这代码写的 彳亍 不 彳亍
* */
FutureTask<String> ft = new FutureTask(() -> "Lambda");
new Thread(ft).start();
System.out.println(ft.get());
/*Lambda好虽好,但如果实现的接口有多个抽象方法需要实现的话
那还是乖乖的用匿名实现类吧*/
/*2.方法的引用
可以使用 类名::静态方法的方式来引用其他类的方法来充当接口方法的实现
* */
Math math3 = LambdaDemo::sum1;
/*非静态方法使用该类类型的变量名或匿名对象均可*/
Math math4 = new LambdaDemo()::sum2;
LambdaDemo ld = new LambdaDemo();
Math math5 = ld::sum2;
/*使用这种方式的前提是被引用的方法必须和接口中的抽象方法有相同方法形参数量,并且每个位置
* 上的形参类型是相同或比其更高范围的类型(引用数据类型需要是它的父结构),虽然允许这种定义方式,但实际调用时还是要传递与抽象方法类型一致的参数
* 而返回值类型和抛出的异常则必须是相同类型或者是它的子结构
* 方法名可以任意
* 总之与和传统的定义实现类实现接口的方法规则类似
* 如果没有表达清楚自己试一试就理解了
*/
/*实际应用
* 遍历集合元素
* 集合元素排序
* */
List<String> list = Arrays.asList(new String[]{"abc","def","ghilmn"});
/*这里的传递的参数是java.util.function.Consumer类型的实例*/
list.forEach(System.out::print);
/*传递一个Comparable类型的参数*/
list.sort((before,after) -> before.length() - after.length());
/*IDEA提示使用这种方式*/
list.sort(Comparator.comparingInt(String::length));
/* 3.构造器
* 如果接口的抽象方法返回值是一个XX引用数据类型,
* 可以通过 XX:new 的方式调用XX构造器来获得一个XX实例作为其方法的返回值
* */
LambdaDemoBuilder ldb = LambdaDemo::new;
/* 4.@FunctionalInterface
* 函数式接口注解:像上面的Math接口就符合这种格式
* 在forEach()中传递的参数Consumer也是被此注解修饰的接口
* 即接口内只能有一个抽象方法
* 此注解不是必须的,但加上可以被编译器更好的检测
* 如果修饰的接口不满足函数式接口的定义则编译无法通过
* 这种接口又叫做SAM(Single Abstract Method)接口
* */
}
}
确实,清爽简洁的代码确实便于维护
Lambda牛哔