lambda表达式也称函数式编程 自己在学习java的时候才接触到了lambda表达式 看到lambda表达式会让代码看起来非常精简 我看了一下网上的学习资料也不少 自己整理一下顺便写一下自己的看法 比较简单 希望我的博客可以带给别人帮助 以及方便自己以后进行回顾和总结
-
Lambda表达式的组成
java 8 中Lambda 表达式由三个部分组成:第一部分为一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数;第二部分为一个箭头符号:→;第三部分为方法体,可以是表达式和代码块。语法如下
-
方法体为表达式 该表达式的值作为返回值返回
(parameters) -> expression (int a,int b) -> return a + b; //求和
-
方法体为代码块 必须用{}包裹起来 并且需要一个return返回值 如果函数式接口里面的方法返回值是void 则无需返回
(parameters) -> { statements; } (int a) -> {System.out.println("a = " + a);} //打印,无返回值 (int a) -> {return a * a;} //求平方
-
Lambda表达式的底层实现
java8中Lambda表达式的实现方式本质是以匿名内部类的形式来实现的 看下面的代码 定义了一个binaryOperator的lambda表达式 它的返回值是一个IntBinaryOperator的实例
IntBinaryOperator binaryOperator = (int a, int b) -> { return a + b; }; int result = binaryOperator.applyAsInt(1, 2); System.out.println("result = " + result); //3
看一下IntBinaryOperator的定义
@FunctionalInterface public interface IntBinaryOperator { /** * Applies this operator to the given operands. * @param left the first operand * @param right the second operand * @return the operator result */ int applyAsInt(int left, int right); }
可以看到IntBinaryOperator是一个接口并且上面有一个@FunctionalInterface的注解 这个注解就是标注了这是一个函数式接口 所以可以知道 (int a, int b) -> {return a + b;}返回的是一个IntBinaryOperator的匿名实现类
-
Lambda表达式的应用场景
-
使用()->{ }替代匿名类
Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("no use lambda"); } }); Thread t2 = new Thread(() -> System.out.println("use lambda"));
可以看出来lambda表达式要比匿名内部类代码看起来简洁很多
-
用内部迭代取代外部迭代
外部迭代:描述要怎么做 代码里嵌套2个以上的for循环都比较难读懂 只能顺序处理List中的元素
内部迭代:描述要做什么 不一定需要顺序处理List中的元素List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API"); for (String feature : features) { System.out.println(feature); //外部迭代 } List features = Arrays.asList("Lambdas", "Default Method", "Stream API","Date and Time API"); features.stream.forEach(n -> System.out.println(n)); //内部迭代
-
要保持lambda表达式的精简和一目了然
values.stream() .mapToInt(e -> { int sum = 0; for(int i = 1; i <= e; i++) { if(e % i == 0) { sum += i; } } return sum; }) .sum()); //代码复杂难懂 values.stream() .mapToInt(e -> sumOfFactors(e)) .sum() //代码简洁一目了然
太长的lambda表达式是非常不好的 因为代码越长越不容易看懂 并且代码也不太容易复用 测试难度也大
注意:lambda表达式只能标记了final修饰的外层局部变量 不能再lambda表达式内部修改定义在域外的局部变量 否则会编译错误