Java8新特性——Lambda表示式

94 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

👨‍🎓作者:Java学术趴

🏦仓库:GithubGitee

✏️博客:CSDN掘金InfoQ云+社区

💌公众号:Java学术趴

🚫特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系小编授权。

🙏版权声明:文章里的部分文字或者图片来自于互联网以及百度百科,如有侵权请尽快联系小编。微信搜索公众号Java学术趴联系小编。

☠️每日毒鸡汤:放心,闭上眼,睡一觉,反正明天也不一定比今天好。

1.1 Java8的新特性

1.2 Java8新特性的特点

  • 速度快。

  • 代码更少(增加了新的语法:Lambda表达式)

  • 强大的Stream API

    • 并行流: 就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。相比串行的流,并行流可以很大程度上提高程序的执行效率。
    • Java 8 中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API 可以声明性地通过 parallel()sequentail() 在并行流与顺序流之间进行切换。
  • 便于并行

  • 最大化减少空指针异常:Optional

  • Nashorn引擎,允许在JVM上运行JS应用

1.3 Lambda表示式

1.3.1 为什么使用 Lambda 表达式

  • Lambda是一个 匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码能像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码,作为一个更紧凑的代码风格,使Java的语言表达能力得到了提升。

Lambda表达式简单的用法

使用Lambda表达式来替换匿名函数

使用Lombda表达式编写内置函数以及调用方法

1.3.2 Lombda表达式使用(分为6中情况使用)

// Lombda的使用,语法介绍
(o1,o2) -> Integer.compare(o1,o2);
格式:
    -> : lambda操作符 或 箭头操作符
    ->左边 :lambda形参列表(其实就是接口中的抽象方法的形参列表)
    ->右边:lambda体(其实就是重写的抽象方法的方法体)

1.3.2.1 语法格式一:无参无返回值

public static void main(String[] args) {
​
    // lambda表达式的第一种语法,无参无返回值
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("我是原始的写法");
        }
    };
​
    runnable.run();
​
    // 使用lambda表达式
    Runnable runnable1 = () -> System.out.println("我是lambda写法");
    
}

1.3.2.2 语法格式二:有一个参数,但是没有破返回值


public static void main(String[] args) {
​
    // lambda表达式的第二种语法,有一个参数,但是没有返回值
    Consumer<String> consumer = new Consumer<String>() {
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    };
    consumer.accept("我是原始的方法");
    
    Consumer<String> consumer1 = (String s) -> {
        System.out.println(s);
    };
    consumer1.accept("我是lambda方法");
}

1.3.2.3 语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”


Consumer<String> consumer2 = (s) -> {
    System.out.println(s);
};
consumer1.accept("我是数据推断的方法");

1.3.2.4 语法格式四:Lambda若只需要一个参数时,参数的小括号可以省略


Consumer<String> consumer2 = s -> {
    System.out.println(s);
};
consumer1.accept("当只存在一个参数的时候,小括号可以省略");

1.3.2.5 语法格式五:Lambda需要两个或两个以上的参数,并且存在多条执行语句,并且可以有返回值


Comparator<Integer> com2 = (o1,o2) -> {
  System.out.println(o1);
  System.out.println(o2);
  return o1.compareTo(o2);
}
// 此时参数需要有小括号,代码块需要有花括号

1.3.2.6 语法六:当Lambda体只有一条语句的时候,大括号可以省略,如果这一条语句是return语句,还可以省略 return


Comparator<Integer> com2 = (o1,o2) -> {
  return o1.compareTo(o2);
}
// 此时函数体只存在一条语句,并且是return语句,可以省略函数体的花括号并且可以省略 return 关键字 
Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);

1.4 函数式接口

1.4.1 函数式接口的概念

  • 只包含一个抽象方法的接口,称为函数式接口。
  • 你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常 即:非运行时异常,那么该异常需要在目标接口的抽象方法上进行声明)。
  • 我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。同时 Javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
  • 在 java.util.function 包下定义了Java8的丰富的函数式接口。

1.4.2 如何理解函数式接口

  • Java从诞生开始就一直倡导“一切皆对象”,在Java里面面向对象(OOP)编程是一切。但是随着Python、scala等语言的兴起和新技术是的挑战,Java不得不做出调整以便支持更加广泛的技术要求,也即Java不但可以支持OOP还可以支持OOF(面向函数编程)
  • 在函数式编程语言中,函数被当做一等公民对待。在将函数作为一等公民的编程语言中,Lambda表达式的类型是函数。但是在Java8中,有所不同。在Java8中,Lambda表达式是对象,而不是函数,他们必须依附于一类特别的对象类型——函数式接口。
  • 简单的说,在Java8中,Lambda表达式就是一个函数式接口的实例。 这就是Lambda表达式和函数式接口的关系。也就是说,只要一个对象是函数式接口的实例,那么该对象就可以使用 Lambda 表达式来表示。
  • 所以以前用匿名实现类表示的现在都可以用 Lambda 表达式来写。