Lambda表达式 | 8月更文挑战

·  阅读 331

Lambda表达式

Lambda表达式的介绍:Lambda表达式是Java8中最重要的新功能之一。使用Lambda表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁移动。Lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作。

Lambda表达式的使用:

代码简化过程

import java.util.*;

public class LambdaDemo {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("running");
            }
        });
        thread.start();

        //lambda写法
        new Thread(()->{System.out.println("running2……");}).start();

        System.out.println("------------------------");
        List<String> list = Arrays.asList("java","javascript","scala","python");
        Collections.sort(list,new Comparator<String>(){
            @Override
            public int compare(String o1, String o2){
                return o1.length()-o2.length();
            }
        });

        for(String str:list){
            System.out.println(str);
        }
        System.out.println("----------------------------------");
        Collections.sort(list,(o1,o2)->o1.length()-o2.length());
        list.forEach(System.out::println);
    }
}
复制代码

函数式接口:

什么是函数式接口:只有一个抽象方法(Object类中的方法除外)的接口是函数式接口。

常用的函数式接口:

1.Supplier:代表一个输出;

2.Consumer:代表一个输入;

3.BiConsumer:代表两个输入;

4.Function:代表一个输入、一个输出(一般输入和输出是不同类型);

5.UnaryOperator:代表一个输入,一个输出(输入和输出是相同类型的);

6.Function:代表两个输入,一个输出(输入和输出是不同类型的);

7.BinaryOperator:代表两个输入,一个输出(输入和输出是相同类型的);

测试代码如下:

ArrayList<Student> list = new ArrayList<>();
list.add(new Student("zhangsan",14,67));
list.add(new Student("lisi",13,89));
list.add(new Student("wangwu",15,97));
list.add(new Student("maliu",12,63));
list.add(new Student("zhaoqi",17,75));

//查找年龄大于14的学生
System.out.println("查找年龄大于14的学生");
findByAge(list);
//查找分数大于75的学生
System.out.println("查找分数大于75的学生");
findByScore(list);
}

public static void findByAge(ArrayList<Student> students){
    ArrayList<Student> list = new ArrayList<>();
    for(Student student:students){
        if(student.getAge() > 14){
            list.add(student);
        }
    }
    for(Student student:list){
        System.out.println(student);
    }
}

public static void findByScore(ArrayList<Student> students){
    ArrayList<Student> list = new ArrayList<>();
    for(Student student : students){
        if(student.getScore() > 75){
            list.add(student);

        }
    }

    for(Student student : list){
        System.out.println(student);
    }
}
复制代码

使用lambda优化

方法一:

//lambda写法优化一:子类实现
package why2;

import why.Student;

public interface StudentFilter {
    boolean compare(Student student);
}
复制代码

方法二:

优化二:直接在类中实现StudentFilter方法,不创建子类:
//查找年龄大于14的学生
System.out.println("查找年龄大于14的学生");
getByFilter(list, new StudentFilter() {
    @Override
    public boolean compare(Student student) {
        return student.getAge() > 14;
    }
});

//查找分数大于75的学生
System.out.println("查找分数大于75的学生");
getByFilter(list, new StudentFilter() {
    @Override
    public boolean compare(Student student) {
        return student.getScore() > 75;
    }
});

//名字长度
System.out.println("查找名字长度大于4的学生");
getByFilter(list, new StudentFilter() {
    @Override
    public boolean compare(Student student) {
        return student.getName().length() > 4;
    }
});
复制代码

优化三:

优化三:不写方法,直接表达式上:
//查找年龄大于14的学生
System.out.println("查找年龄大于14的学生");
getByFilter(list, (e)->e.getAge() > 14);
//查找分数大于75的学生
System.out.println("查找分数大于75的学生");
getByFilter(list, (e)->e.getScore() > 75);

//名字长度
System.out.println("查找名字长度大于4的学生");
getByFilter(list, (e)->e.getName().length() > 4);
复制代码

方法的引用:

1.方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用调用另一个方法来实现,就有可能可以使用方法引用。

2.方法引用的分类:

2.1:静态方法:如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用;

2.2:实例方法引用:如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用;

2.3:对象方法引用:抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当作实例方法的参数。如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用;

2.4:构造方法引用:如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用。

类型语法对应的 lambda 表达式
静态方法引用类名::staticMethod(args)->类名.staticMethod(args)
实例方法引用inst::instMethod(args)->instMethod(args)
对象方法引用类名::instMethod(inst,srgs)->类名.instMethod(args)
构造方法引用类名::new(args)->new 类名(args)

Java Stream API

1.Stream是一组用来处理数组、集合的API;

2.Java8之所以费这么大劲引入函数式编程,原因有二:

2.1:代码简洁,函数式编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环;

2.2:多核友好,Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下parallel()方法。

3.Stream特性:

3.1:不是数据结构,没有内部存储;

3.2:不支持索引访问;

3.3:延迟计算;

3.4: 支持并行;

3.5:很容易生成数组或集合;

3.6:支持过滤,查找,转换,汇总,聚合等操作。

4.Stream运行机制

4.1:Stream分为源source,中间操作,终止操作;

4.2:流的源可以是一个数组、一个集合、一个生成器方法、一个I/O通道等等;

4.3: 一个流的操作可以有零个或者多个中间操作,每个中间操作都会返回一个新的流,供下一个操作使用。一个流只会有一个终止操作;

4.4: Stream只有遇到终止操作,它的源才开始执行遍历操作。

5.Stream的创建:

5.1:通过数组;

5.2:通过集合;

5.3: 通过Stream.generate来创建;

5.4: 通过Stream.iterate方法来创建;

5.5:其他API创建。

分类:
后端
标签: