数据结构系列17——lambda表达式

目录

1. 基本概念

2. 基本语法

3. 函数式接口

4. Lambda表达式的基本使用 

4.1 语法精简

5. 变量捕获

6. Lambda在集合当中的使用


1. 基本概念

        Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。

2. 基本语法

基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }

Lambda表达式由三部分组成:
1. paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。
2. ->:可理解为“被用于”的意思
3. 方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不返回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不返回。

// 1. 不需要参数,返回值为 2
() -> 2
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的和
(x, y) -> x + y
// 4. 接收2个int型整数,返回他们的乘积
(int x, int y) -> x * y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)

3. 函数式接口

        要了解Lambda表达式,首先需要了解什么是函数式接口,函数式接口定义:一个接口有且只有一个抽象方法 。

注意:
1. 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口
2. 如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接
口,这样如果有两个抽象方法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接口中只
有一个抽象方法,你可以不加这个注解。加上就会自动进行检测的。

定义的方式

@FunctionalInterface
interface NoParameterNoReturn {
//注意:只能有一个方法
  void test();
}

回顾:这里简要回顾一下抽象方法和抽象类以及接口中的下相关知识

抽象方法:

        java中的抽象方法就是以abstract修饰的方法,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。

抽象方法与抽象类:

        当一个方法为抽象方法时,意味着这个方法应该被子类的方法所重写,否则其子类的该方法仍然是abstract的,这个子类由于继承父类,拥有抽象方法,因此它也是抽象类,即声明为abstract。abstract抽象类不能用new实例化对象,abstract方法只允许声明不能实现。如果一个类中含有abstract方法,那么这个类必须用abstract来修饰,当然abstract类也可以没有abstract方法。 一个抽象类里面没有一个抽象方法可用来禁止产生这种类的对象。

抽象方法与接口:

        在interface中所有的方法都是public abstract的,即使你没有声明它是public abstract的。在interface中所有的数据成员都是public static final的,即使你没有声明.但不能是blank final 在编译时候确定的。在java中,interface的地位和class是一样的。实现interface的类,其interface中所有的方法必须被“实现”,否则这个类成为一个抽象类。Interface可以从多个interface得到继承,但是不能继承类。一个类可以实现多个interface。

回到正题

lambda表达式在jdk1.8有了新的特性,可以有静态成员方法和默认的方法

数据结构系列17——lambda表达式_第1张图片

4. Lambda表达式的基本使用 

1.首先定义了六个接口(并且是函数式接口)

数据结构系列17——lambda表达式_第2张图片

 2. 使用lambda表达式使用这些接口

public class test {
    public static void main1(String[] args) {
        NoParameterNoReturn noParameterReturn = new NoParameterNoReturn() {
            //1. 正常情况下使用接口,需要重写接口的方法
            @Override
            public void test() {
                System.out.println("hello");
            }
        };
    }

    public static void main(String[] args) {
        //1.此时为没有参数没有返回值的lambda表达式
        NoParameterNoReturn noParameterNoReturn = ()->{System.out.println("hello");};
        noParameterNoReturn.test();

        //2.含有一个参数,没有返回值的lambda表达式
        //                                     此时可以省略括号与参数类型 还有大括号
        OneParameterNoReturn oneParameterNoReturn = (int x)->{System.out.println(x+10);};
        oneParameterNoReturn.test(10);

        //3.含有多个参数,没有返回值的lambda表达式
        //                                            不能省略括号,类型不能单独省略,只能同时省略
        MoreParameterNoReturn moreParameterNoReturn = (int x, int y)->{
            System.out.println(x+y);
        };
        moreParameterNoReturn.test(1,2);

        //4.没有参数有返回值
        //                                        此时可以省略return
        NoParameterReturn noParameterReturn = ()->{return 10;};
        int ret1 = noParameterReturn.test();
        System.out.println(ret1);

        //5.一个参数有返回值
        //                                    能省略括号;可以省略return
        OneParameterReturn oneParameterReturn = (x)->{return x;};
        int ret2 = oneParameterReturn.test(10);
        System.out.println(ret2);

        //6.一个参数有返回值
        //                                    不能省略括号;可以省略return
        MoreParameterReturn moreParameterReturn = (int x, int y)->{return x*y;};
        MoreParameterReturn moreParameterReturn2 = (x, y)->x * y;;
        int ret3 = moreParameterReturn.test(10,20);
        System.out.println(ret3);
    }
}

运行结果: 

数据结构系列17——lambda表达式_第3张图片

4.1 语法精简

1. 参数类型可以省略,如果需要省略,每个参数的类型都要省略。
2. 参数的小括号里面只有一个参数,那么小括号可以省略
3. 如果方法体当中只有一句代码,那么大括号可以省略
4. 如果方法体中只有一条语句,且是return语句,那么大括号可以省略,且去掉return关键字。

5. 变量捕获

1. 匿名内部类简单使用

数据结构系列17——lambda表达式_第4张图片

2. 匿名内部类的变量捕获

数据结构系列17——lambda表达式_第5张图片

在上述代码当中的变量a就是,捕获的变量。这个变量要么是被final修饰,如果不是被final修饰的 你要保证在使用之前,没有修改。

 数据结构系列17——lambda表达式_第6张图片

 3. Lambda的变量捕获

数据结构系列17——lambda表达式_第7张图片

6. Lambda在集合当中的使用

1.List接口

1.1sort()方法的演示

该方法根据c指定的比较规则对容器元素进行排序。

数据结构系列17——lambda表达式_第8张图片

 运行结果:数据结构系列17——lambda表达式_第9张图片

1.2 forEach

数据结构系列17——lambda表达式_第10张图片

 运行结果数据结构系列17——lambda表达式_第11张图片

2. map

forEach

此处就是与Sort重写的方法不相同,看源码为:

数据结构系列17——lambda表达式_第12张图片

数据结构系列17——lambda表达式_第13张图片

 那么就需要重写accept函数,进行使用lambda表达式

数据结构系列17——lambda表达式_第14张图片

你可能感兴趣的:(数据结构,数据结构,java)