当前位置:   article > 正文

JDK 8新特性——Lambda表达式_java8优雅开启线程

java8优雅开启线程

一、函数式编程思想概述

https://www.runoob.com/java/java8-lambda-expressions.html

在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作”

面向对象强调“必须通过对象的形式来做事情”,做事情之前首先要创建一个对象

函数式思想则尽量忽略面向对象的复杂语法:”强调做什么,而不是以什么形式去做”,我们要学习的Lambda表达式就是函数式思想的体现

什么是函数式接口呢?就是一个接口有且只有一个抽象方法。

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。

  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。

  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。

1.1需求:启动一个线程,在控制台输出一句话:多线程启动了

1.1.1 方式一 创建类实现Runnable接口

  • 定义一个类MyRunnable实现Runnable接口,重写run()方法

  • 创建MyRunable类对象

  • 创建Thread类的对象,把MyRunnable的对象作为构造参数传递

  • 启动线程

  1. public class MyRunnable implements Runnable{
  2. @Override
  3. public void run() {
  4. System.out.println("多线程程序启动了");
  5. }
  6. }
  1. public class LambdaTest {
  2. public static void main(String[] args) {
  3. MyRunnable my = new MyRunnable();
  4. Thread t = new Thread(my);
  5. t.start();
  6. }
  7. }

1.1.2 方式二 匿名内部类

  1. new Thread(new Runnable() {
  2. @Override
  3. public void run() {
  4. System.out.println("ssss");
  5. }
  6. }).start();

1.1.3 方式三 lambda表达式

简洁,不用创建类

  1. new Thread( ()->{
  2. System.out.println("多线程程序启动");
  3. }).start();

1.2 Lambda表达式的代码式使用分析

  1. new Thread( ()->{
  2. System.out.println("多线程程序启动");
  3. }).start();
  • ():里面没有内容,可以看成是方法形式参数为空

  • ->:用箭头指向后面要做的事情

  • {}:包含一段代码。我们称之为代码块

(形式参数)->{代码块}

  • 形式参数:如果有多个参数,参数之间用逗号隔开。

类似于方法的形参列表,这里指的是函数式接口中抽象方法的参数。参数的类型即可以声明也可以省略,如果只有一个参数,括号也可以省略

  • ->:由英文中划线和大于符号组成,固定写法,代表指向动作

  • 代码块:我们具体要做的事情

二、Lambda表达式练习

2.1 抽象方法无参无返回值

  1. public interface Eatable {
  2. void eat();
  3. }

  1. public class EatableImpl implements Eatable{
  2. @Override
  3. public void eat() {
  4. System.out.println("好好好");
  5. }
  6. }

  1. public class EatableDemo {
  2. public static void main(String[] args) {
  3. Eatable e = new EatableImpl();
  4. userEatable(e);
  5. }
  6. private static void userEatable(Eatable e){
  7. e.eat();
  8. }
  9. }

上面的代码可以简化

  1. userEatable(()->{
  2. System.out.println("好好好");
  3. } );

下面这个就不需要实现类的

  1. public class EatableDemo {
  2. public static void main(String[] args) {
  3. userEatable(()->{
  4. System.out.println("好好好");
  5. } );
  6. }
  7. private static void userEatable(Eatable e){
  8. e.eat();
  9. }
  10. }

2.1.1 匿名内部类与lambda表达式直接对比

  1. @FunctionalInterface
  2. public interface AcanthopanaxInterface {
  3. void get();
  4. }

  1. public class Test03 {
  2. public static void main(String[] args) {
  3. // 1.使用匿名内部类的方式进行
  4. new AcanthopanaxInterface(){
  5. @Override
  6. public void get() {
  7. System.out.println("get");
  8. }
  9. }.get();
  10. // 2.lambda表达式
  11. AcanthopanaxInterface acanthopanaxInterface = () -> {
  12. System.out.println("使用lambda表达式的调用方法");
  13. };
  14. acanthopanaxInterface.get();
  15. }
  16. }

2.2 抽象方法带参无返回值

定义接口

  1. public interface Flyable {
  2. void fly(String s);
  3. }

  1. public class FlyableDemo {
  2. public static void main(String[] args) {
  3. userFlyable( (String s)->{
  4. System.out.println(s);
  5. System.out.println("好好好");
  6. });
  7. }
  8. private static void userFlyable(Flyable f){
  9. f.fly("风和日丽");
  10. }
  11. }

拆开看一下

  1. public class FlyableDemo {
  2. public static void main(String[] args) {
  3. Flyable flyable = (String s) -> {
  4. System.out.println(s);
  5. System.out.println("好好好");
  6. };
  7. userFlyable(flyable);
  8. }
  9. private static void userFlyable(Flyable f){
  10. f.fly("风和日丽");
  11. }
  12. }

2.3 抽象方法带参带返回值

  1. public class AddableDemo {
  2. public static void main(String[] args) {
  3. userAddable( (int x,int y)->{
  4. return x+y;
  5. });
  6. }
  7. private static void userAddable(Addable a){
  8. int sum = a.add(10,20);
  9. System.out.println(sum);
  10. }
  11. }

a.add(10,20)中的10和20最终传递给了int x,int y,然后通过lambda表达式将x与y相加并返回给sum

  1. public interface Addable {
  2. int add(int x,int y);
  3. }

如果上面的不好理解我们就拆分出来

一定要看一下注释信息

  1. public class AddableDemo {
  2. public static void main(String[] args) {
  3. // Addable addable = (x, y) -> {
  4. // return x + y;
  5. // };
  6. // 下面的程序就是这句话userAddable(addable);
  7. userAddable((x, y) -> {
  8. return x + y;
  9. });
  10. }
  11. private static void userAddable(Addable a){
  12. int sum = a.add(10,20);
  13. System.out.println(sum);
  14. }
  15. }

2.3.1 匿名内部类与lambda表达式的对比

  1. @FunctionalInterface
  2. public interface YouShenInterface {
  3. String get(int i,int j);
  4. }
  1. public class Test04 {
  2. public static void main(String[] args) {
  3. // 1.匿名内部类的形式
  4. YouShenInterface youShenInterface = new YouShenInterface() {
  5. @Override
  6. public String get(int i, int j) {
  7. return i + "---" + j;
  8. }
  9. };
  10. System.out.println(youShenInterface.get(1,1));
  11. // 2. lambda表达式的形式
  12. YouShenInterface youShenInterface1 = (i, j) -> {
  13. return i + "---" + j;
  14. };
  15. System.out.println(youShenInterface1.get(1,2));
  16. }
  17. }

三、Lambda表达式的省略模式

3.1 参数的类型可以省略

虽然能省略,但是多个参数的情况下不能只省略一个

  1. userAddable( ( x, y)->{
  2. return x+y;
  3. });

3.2 参数有且只有一个,参数可以省略

  1. public class FlyableDemo {
  2. public static void main(String[] args) {
  3. userFlyable( s->{
  4. System.out.println(s);
  5. });
  6. }
  7. private static void userFlyable(Flyable f){
  8. f.fly("风和日丽");
  9. }
  10. }

3.3 代码块语句只有一条,可以省略大括号和分号

  1. public class FlyableDemo {
  2. public static void main(String[] args) {
  3. userFlyable( s->System.out.println(s) );
  4. }
  5. private static void userFlyable(Flyable f){
  6. f.fly("风和日丽");
  7. }
  8. }

3.4 代码块语句只有一条,return也要省略掉

        userAddable( ( x, y)-> x+y);

四、注意事项

  • 有一个接口(抽象类不可以),接口中有且只有一个抽象方法

  • 使用lambda的时候必须有上下文环境,才能推导出Lambda对应的接口

匿名内部类编译之后会多出一个“.class”文件,而lambda不会多出,lambda字节码会在运行的时候动态生成

匿名内部类可以是接口,可以是抽象类,还可以是具体类

  • @ FunctionalInterface 表示该接口为函数接口

  1. @FunctionalInterface
  2. public interface OrderService {
  3. void get();
  4. }

如下图所示,如果我们再增加一个方法,就会报错

但是我们可以写默认方法

  • Object父类中的方法可以在函数接口中重写

五、集合的遍历与排序

5.1 集合的遍历

  1. public class Test06 {
  2. public static void main(String[] args) {
  3. ArrayList<String> arrayList = new ArrayList<>();
  4. arrayList.add("mayikt");
  5. arrayList.add("zhangin");
  6. arrayList.add("asdasfg");
  7. // 1.匿名内部类的形式
  8. arrayList.forEach(new Consumer<String>() {
  9. @Override
  10. public void accept(String s) {
  11. System.out.println(s);
  12. }
  13. });
  14. // 2.lambda表达式的形式
  15. arrayList.forEach(s->{
  16. System.out.println(s);
  17. });
  18. }
  19. }

5.2 集合的排序

  1. public class Test07 {
  2. public static void main(String[] args) {
  3. ArrayList<UserEntity> userEntityArrayList = new ArrayList<>();
  4. userEntityArrayList.add(new UserEntity("zhangjingqi",30));
  5. userEntityArrayList.add(new UserEntity("fanusbisf",18));
  6. userEntityArrayList.add(new UserEntity("saffawfasx",25));
  7. // 1.匿名内部类排序
  8. userEntityArrayList.sort(new Comparator<UserEntity>() {
  9. @Override
  10. public int compare(UserEntity o1, UserEntity o2) {
  11. return o1.getAge()-o2.getAge();
  12. }
  13. });
  14. userEntityArrayList.forEach((userEntity)->{
  15. System.out.println(userEntity);
  16. });
  17. System.out.println("*************************************");
  18. // 2.lambda表达式排序
  19. userEntityArrayList.sort((o1,o2)->{
  20. return o1.getAge()-o2.getAge();
  21. });
  22. userEntityArrayList.forEach((userEntity)->{
  23. System.out.println(userEntity);
  24. });
  25. }
  26. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/726753
推荐阅读
相关标签
  

闽ICP备14008679号