欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java8新特性-Lambda表达式是什么?

程序员文章站 2022-04-24 07:54:10
[TOC] 前言 Java8新特性 Lambda表达式,好像很酷炫的样子,直接搬运官方文档: Purpose This tutorial introduces the new lambda expressions included in Java Platform Standard Edition ......

目录

前言

Java8新特性-Lambda表达式,好像很酷炫的样子,直接搬运官方文档:

Purpose
This tutorial introduces the new lambda expressions included in Java Platform Standard Edition 8 (Java SE 8).

Time to Complete
Approximately 1 hour

Introduction
Lambda expressions are a new and important feature included in Java SE 8. They provide a clear and concise way to represent one method interface using an expression. Lambda expressions also improve the Collection libraries making it easier to iterate through, filter, and extract data from a Collection. In addition, new concurrency features improve performance in multicore environments.

所以学习这么酷炫的东西其实只需要大约一个小时就足够了;
介绍里面只有一句重点,其他都是废话:

Lambada表达式: 它们通过使用表达式来提供一种清晰简洁的方式来表示方法接口

然而,我还是不知道方法接口是个什么东西,直到我看完了文档,才发现这句也是废话;因为这个得懂了Lambada表达式是什么了才能理解这句话;

匿名内部类

学习Lambda表达式之前,先感受下匿名内部类使用:

 Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

            }
        });

以上代码创建一个线程,我们知道得到一个接口实例只能实例化其实现类,但是这里我并没有创建一个具体的实现类,因为我不需要再次使用它;而是使用了匿名内部内代替,这样让我的代码更紧凑简洁;

函数式接口 和 Lambda表达式语法

函数式接口:

  • Java8 将只有一个抽象方法的接口叫做 函数式接口

  • @FunctionalInterface注解只是显示表示这个接口是函数式接口,在定义函数式接口时就会检查是否符合函数式接口规范,Java自己实现的函数式接口都有这个注解,所以你懂的,规范是好事情

Lambda表达式语法(三部分组成):

参数列表 -> 方法体
比如: (int x)-> {System.out.println(x);}

实现函数式接口并使用Lambda表达式:

@FunctionalInterface
interface  A{
    void opration();

}

class B {
    void realOpration(A fi){
        fi.opration();
    }

}
public class Tests {

    @Test
    public void test(){
        B b = new B();
        b.realOpration(()-> System.out.println("opration"));
    }

}

所以Lambda表达式是什么?

看了上面简单的demo,所以Lambda表达式干了什么事情,()->System.out.println("opration") 就是函数式接口的抽象方法的实现,只是用了一种特殊的非常简洁的形式来表示而已,那么这种表示方法就是Lambda表达式;为什么这么简洁,因为它不仅是匿名类,还特么把方法都匿名了,它自动将Lambda表达式绑定到函数式接口的抽象方法;说白了,其实就是搞了一个接口,实现了一个回调函数(方法),看起来就好像是函数式编程一样;

所以为什么函数式接口只能有一个抽象方法?

我一开始想是因为方法多了就不知道Lambda表达式对应的哪个方法了;然后我想了一下为什么不能多个同名方法,Lambda表达式也可以重载啊,后来我再一想发现傻逼了,函数式接口本身的作用就只是相当于有一个空口袋(抽象方法),临时用来包装Lambda表达式的,根本不需要多个方法;

实战应用

再说函数式接口

我们已经知道函数式接口的作用了,但其实我们不需要自己去实现函数接口,Java8已经根据内置了几种不同类型的函数式接口;

  • Predicate: A property of the object passed as argument
  • Consumer: An action to be performed with the object passed as argument
  • Function: Transform a T to a U
  • Supplier: Provide an instance of a T (such as a factory)
  • UnaryOperator: A unary operator from T -> T
  • BinaryOperator: A binary operator from (T, T) -> T

这里没必要一一列举了,如果自己需要实现一个支持Lambda表达式的方法,只需要选用合适的函数式接口就行了,其实只是一种规范;

下面一个demo足够:

Consumer的应用demo

class Class {
    private List<Student> list = new ArrayList<>();
    public void addStudent(Student student){
        list.add(student);
    }
    public void showStudents(Consumer<Student> consumer){
        for (Student student : list){
            consumer.accept(student);
        }
    }
}
class Student{
    private String name;
    private char sex;
    private Double height;

    public String getName() {
        return name;
    }

    public Student setName(String name) {
        this.name = name;
        return this;
    }

    public char getSex() {
        return sex;
    }

    public Student setSex(char sex) {
        this.sex = sex;
        return this;
    }

}
public class Tests {
    @Test
    public void test(){
        Class clazz = new Class();
        clazz.addStudent(new Student().setName("000").setSex('男'));
        clazz.addStudent(new Student().setName("002").setSex('女'));
        clazz.showStudents((s)-> System.out.println(s.getName()));
    }

}

总结

Lambda表达式在Java8中的应用比较多,特别是对集合类的操作;
比如sort方法、foreach方法等等;其中Stream API也是一大特点,但是也不过是对函数式接口的具体应用,需要了解的时候看看API文档或者源码就行了;所以总的来说,就是为了简化代码,封装我们的操作,所以引入了函数式接口的概念,而Lambda表达式表示了函数式接口中抽象方法的匿名实现;

综上:

They provide a clear and concise way to represent one method interface using an expression.