1.Java8新特性

发布时间 2023-11-17 22:35:03作者: 求知律己

1.Lambda表达式

 1.1 概述

  Lambda表达式是一种函数式编程函数编程思想)方式,用于替代匿名内部类。它使得代码更具有可读性和简洁性,并提供更好的代码复用性和可维护性

面向对象编程思想

  强调的是对象必须通过对象来完成操作,情况较复杂。例如:多线程执行任务,需要创建对象。首先定义一个实现类实现接口Runnable,然后重写run方法中的代码传递给线程对象,这么麻烦?直接执行不就好了吗?

函数编程思想

  函数需要得有输入量输出量,使用输入量计算得到输出量。为了尽量忽略对象的复杂用法---强调做什么,而不是以什么去做。

  同样执行线程任务,使用函数编程思想,可以直接通过传递一段代码给线程对象执行不需要创建任务对象

小结函数编程思想可以通过一段代码完成面向对象想要做的代码量

1.2 Lambda表达式格式

1.2.1 标准格式

(参数列表)->{代码}

1.2.2 格式说明

  1. 小括号内的语法与接口中的方法括号里面的参数列表一致,空参数则空,多个参数逗号(",")隔开;
  2. ->新引入的语法格式,表示指向动作;
  3. 大括号内的内容与接口实现类中方法体的内容一致

1.2.3 代码实例

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("第一种创建线程方式");
            }
        }).start();
        
        new Thread(()->{
            System.out.println("更简洁地方法创建多线程");
        }).start();
    }

运行结果

  在上述代码中,我们可以看到使用lambda表达式,省去了创建接口的流程(new Runnable),连里面的方法(run()方法)都省去只保留方法中的内容

List<Integer> list = new ArrayList<>();
        //为列表一次性添加多个元素
        Collections.addAll(list, 11,22,33,44,55);
        System.out.println(list);
        //比较器的正常书写格式
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;//后面数减前面数是降序排列
            }
        });
        System.out.println(list);
        //lambda表达式
        Collections.sort(list,(Integer o1, Integer o2)->{ return o1 -o2;});//前面数减后面数是升序排列
        System.out.println(list);

运行结果

1.3 Lambda表达式使用的条件

  首先,都是接口,且接口中只有一个抽象方法才可以使用Lambda表达式

  1. 接口中只有一个抽象方法,叫函数式接口
  2. 如果是函数式接口,可以用@FunctionInterface注解标识

   在上图中,Runnable是一个接口,其只有一个抽象方法,且被@FunctionInterface注解标识,只需满足其中一个就可以使用Lambda表达式。

1.4 Lambda 表达式的简写格式

  1. 小括号中的形参类型可以省略
  2. 如果小括号中只有一个参数的话,那么小括号可以省略
  3. 如果大括号中只有一条语句,那么大括号、分号、return可以一起省略
new Thread(()->System.out.println("更简洁的线程创建")).start();
运行结果
更简洁的线程创建
//继续简化lambda表达式
        Collections.sort(list, (o1, o2)->o2-o1);

运行结果
[55, 44, 33, 22, 11]

1.5 Lambda表达式的表现形式

1.变量的形式:变量为函数式接口,就么可以复制一个Lambda表达式【不常用】

        // 变量的形式
        Runnable r = ()->{
            System.out.println("任务代码");
        };
        // 函数式接口类型的变量
        Thread t = new Thread(r);

2.参数的形式:方法的形参为函数式接口,就可以传入一个Lambda表达式【常用】

        // 变量的形式-比较器
        Comparator<Integer> comparable = (o1, o2)->{return o2 - o1;};
        // 创建集合
        ArrayList<Integer> list = new ArrayList<>();
        // 存入数据
        Collections.addAll(list,11,22,33,44,55);
 
        // 将函数式接口类型  的 形参类型,传给Collections
        Collections.sort(list,comparable);

3.返回值的形式:方法的返回值类型为函数式接口,就可以返回一个Lambda表达式【常用】

        // 定义一个方法
        public static Comparator<Integer> getComparator(){
            return (Integer o1,Integer o2)->{return  o2-o1;};
        }
        
        public static void main (String[] args) {
            // 返回值形式
            Collections.sort(list,getComparator());
        }

2.Stream流

  Stream流是一种用于处理集合数据进行数据操作API。它提供了一种简单而强大的方法,可以以声明式的方式对集合进行过滤映射排序分组等操作。

2.1 Stream流引入

问题

  1. 将list集合中姓张的元素过滤到一个新的集合中
  2. 然后将过滤出来的姓张的元素中,再过滤出来长度为3的元素,存储到一个新的集合中

代码实例

//①将list集合中姓张的元素过滤到一个新的集合中
        //②然后将过滤出来的姓张的元素中,再过滤出来长度为3的元素,存储到一个新的集合中
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "张老三", "张小三", "李四", "王五", "张六", "赵八");
        List<String> list1 = new ArrayList<>();
        for (String name:list) {
            if (name.startsWith("张")){
                list1.add(name);
            }
        }
        System.out.println(list1);
        List<String> list2 = new ArrayList<>();
        for (String name:list1) {
            if (name.length() == 3){
                list2.add(name);
            }
        }
        System.out.println(list2);
普通方法

运行结果

[张老三, 张小三, 张六]
[张老三, 张小三]

用Stream流操作集合,获取流,过滤操作,打印输出

list.stream().filter((String name)->name.startsWith("张"))
                //方法体中只有一个形参时可省略小括号,方法体中只有一个语句时可省略大括号
                    .filter(name -> name.length() == 3)
                    //遍历
                    .forEach(name -> System.out.println(name));

运行结果

张老三
张小三