【摘要】Lambda表达式~
前言 没有前言~
lambda表达式概念 概念 λ是希腊字母表中排序第十一位的字母,英语名称为lambda。为了避免匿名内部类定义过多,Java8引入这一新特性。其实质是函数式编程的概念。
语法格式 1 2 3 (params)->expression (params)->statement (params)->{statements}
借助Runnable推导演示 普通方式启动线程 比如创建线程时,我们只需要关注线程体(内容),而不需要线程类和结构。先来看一下这个代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.aiz.se.lambda;public class StartRun implements Runnable { @Override public void run () { for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } public static void main (String[] args) { new Thread(new StartRun()).start(); for (int i = 0 ; i < 10 ; i++) { System.out.println("吃爆米花" ); } } }
通过内部类 我们知道一个类如果只是使用一次,我们可以把这个类做成内部类。
1 2 3 4 5 6 7 8 9 10 11 12 13 static class InnerThread1 implements Runnable { @Override public void run () { for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } } public static void main (String[] args) { new Thread(new InnerThread1()).start(); }
通过局部内部类 其实我们可以把上面那个类中的类进行挪动,放在一个方法当中。
1 2 3 4 5 6 7 8 9 10 11 12 public static void main (String[] args) { class InnerThread2 implements Runnable { @Override public void run () { for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } } new Thread(new InnerThread2()).start(); }
通过匿名内部类 1 2 3 4 5 6 7 8 9 new Thread(new Runnable() { @Override public void run () { for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } }).start();
jdk1.8 lambda 相比匿名内部类省略接口名和方法名,但是,这种方式接口里面只能有一个没有实现的方法。
1 2 3 4 5 6 7 new Thread(()->{ for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } ).start();
一般来说比较简单的线程体我们才使用lambda,lambda就是用于简化简单的线程体,jdk8会自己进行推导是Runnable的run()方法。接口中如果有多个没有实现的方法无法则进行推导。
推导总结 通过上面一步一步的推导,我想应该明白了lambda表达式创造的用意和如何进行使用。由于上面每个步骤的代码片段不在一起,下面先放一个总的代码类,方面直接观察。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 package com.aiz.se.lambda;public class LambdaThread { static class InnerThread1 implements Runnable { @Override public void run () { for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } } public static void main (String[] args) { new Thread(new InnerThread1()).start(); class InnerThread2 implements Runnable { @Override public void run () { for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } } new Thread(new InnerThread2()).start(); new Thread(new Runnable() { @Override public void run () { for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } }).start(); new Thread(()->{ for (int i = 0 ; i < 10 ; i++) { System.out.println("喝酸奶" ); } } ).start(); } }
lambda的使用 在推导过程中,考虑到只是简单的推导越简单越好,我使用的是线程相关的Runnable的例子,其中的run()方法并未涉及到返回值和参数。其实在我们实际使用过程中需要参数和返回值,下面我就来介绍如何来使用。 自定义一个接口,其中只包含一个未实现的方法,并且该方法有返回值和参数。下面我定义了一个数学运算的接口。
1 2 3 interface MathOperation { int operation (int a, int b) ; }
为了使用上面数学运算的接口,我们需要定义一个操作的方法。
1 2 3 private int operate (int a, int b, MathOperation mathOperation) { return mathOperation.operation(a, b); }
下面列出全部代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package com.aiz.se.lambda;public class LambdaTester { interface MathOperation { int operation (int a, int b) ; } private int operate (int a, int b, MathOperation mathOperation) { return mathOperation.operation(a, b); } public static void main (String[] args) { LambdaTester tester = new LambdaTester(); MathOperation add = (int a, int b) -> a + b; MathOperation sub = (a, b) -> a - b; MathOperation mul = (int a, int b) -> { return a * b; }; MathOperation div = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10 , 5 , add)); System.out.println("10 - 5 = " + tester.operate(10 , 5 , sub)); System.out.println("10 * 5 = " + tester.operate(10 , 5 , mul)); System.out.println("10 / 5 = " + tester.operate(10 , 5 , div)); } }
注:Lambda 表达式只能用于 functional interface ,而 functional interface 只有一个方法。
经常使用场景
实现Runnable/Comparable/迭代列表/事件监听…
参考
菜鸟教程
结束语 没有结束