jdk8新特性——Lambda表达式、Stream流、方法引用

目录

Lambda表达式

1、概念

2、使用规则

3、代码示例

Stream流

1、概念

2、使用

3、代码示例

方法引用

1、概念

2、适用情况

3、代码示例

总结


Lambda表达式

1、概念

        Lambda表达式为一种函数式编程方式,是jdk8中引入的新特性之一,是针对函数式接口的匿名内部类的实现。它提供了一种更简洁、直观的方式来实现函数式编程,使得代码更加易读和易写。这里的易读大家可能不是很赞同,其实当你用习惯了后,确实会觉得这种方式很爽,简单粗暴,一开始用起来可能不是很适应。下面的例子可以带大家感受一下为啥说简单粗暴!需要注意的是,Lambda只针对函数式接口的匿名内部类!

        函数式接口:是指有且仅有一个抽象方法的接口,被@FunctionalInterface注解标记的接口也是函数式接口。

2、使用规则

  • 只有一个参数时可以省略参数类型和();
  • 两个或两个以上参数的参数类型可以省略;
  • 如果方法体中只有一行代码的 { } 可以省略,同时分号和return也不能出现;

3、代码示例

这里我个人觉得看代码比较直观,就直接上代码了。

    @Test
    public void test1(){
        Map map = new HashMap<>();
        map.put("ahaaa",11);
        map.put("cpx",23);
        map.put("lch",4245);
        map.put("chamu",35);

        Set> entries = map.entrySet();

        // 原本 (这里的stream()等都是Stream流的应用,大家可以先忽略,关注排序sorted()方法里面的变化即可
//        entries.stream().sorted(new Comparator>() {
//            @Override
//            public int compare(Map.Entry o1, Map.Entry o2) {
//                return o2.getValue() - o1.getValue();
//            }
//        }).forEach(e ->  System.out.println(e.getKey()+"----"+e.getValue()));

        // lambda改写后(省略了o1,o2的参数类型、省略了{ }、省略了return和 ; 号)
        entries.stream().sorted((o1, o2) -> o1.getValue() - o2.getValue())
                .forEach(e ->  System.out.println(e.getKey()+"----"+e.getValue()));
    }

Stream流

1、概念

        Stream流也是jdk8中引入的新特性之一,它主要用于处理集合数据,把集合转化成流来操作,把复杂的集合操作以简洁的方式表达出来,具有更高的可读性和可维护性。主要用来结合Lambda表达式语法编程。

2、使用

首先是获取集合的Stream流,然后再进行过滤、排序、去重等等操作。其中数组获取流的方式与集合不同,具体看下列代码演示。

  • 过滤为filter( )方法
  • 排序为sorted( )方法
  • 去重为distinct( )方法
  • 取前几为limit( )方法

注:以上为一些常用的方法,还有其他方法具体可以查看相关api。

3、代码示例

数组

    @Test
    public void test3(){
        // 数组转stream流
        String[] names = {"ahaaaa","cpx","lch","chamu"};

        // 获取流方式1
//        Stream namesStream = Stream.of(names);

        // 获取流方式2
        Stream stream = Arrays.stream(names).;
        // 调用filter()进行过滤,判断集合中的对象e是否包涵“p”,若不包含过滤,然后调用forEach()进行遍历
        stream.filter(e -> e.contains("p")).forEach(e -> System.out.println(e));

    }

集合

    @Test
    public void test1(){
        // list转stream流
        List list = new ArrayList<>();

        list.add("ahaaaa");
        list.add("banana");
        list.add("apple");
        list.add("grapes");
        list.add("watermelon");

        // 调用filter()进行过滤,判断集合中的对象e是否包涵“b”,若不包含过滤,然后调用forEach()进行遍历
        list.stream().filter(e -> e.contains("b")).forEach(e -> System.out.println(e));
        // 调用count()获取集合格个数
        System.out.println(list.stream().count());
    }

方法引用

1、概念

        方法引用是用于简化Lambda表达式的定义,它可以直接引用已有代码中的方法,作为Lambda表达式的替代形式,从而让代码更简洁、更易读。

2、适用情况

  • Lambda表达式中只调用了一个静态方法,并且前后参数一致;
  • Lambda表达式中只调用了一个实例方法,并且前后参数一致;
  • Lambda表达式中只调用了一个实例方法,入参为两个参数,并且第一个参数作为调用方调用第二个参数;

这里结合下面三个代码示例理解比较简单

3、代码示例

第一种适用情况

    @Test
    public void test1(){
        List objects = new ArrayList<>();
        Cat hei = new Cat("小黑", 11);
        Cat bai = new Cat("小白", 23);
        Cat lan = new Cat("小蓝", 45);
        Cat hong = new Cat("小红", 64);

        objects.add(hei);
        objects.add(bai);
        objects.add(lan);
        objects.add(hong);

        // 原本  第一步
//        objects.stream().sorted(new Comparator() {
//            @Override
//            public int compare(Cat o1, Cat o2) {
//                return o1.getAge()-o2.getAge();
//            }
//        }).forEach(e -> System.out.println(e.toString()));

        // 改写成lambda  第二步
//        objects.stream().sorted((o1, o2) -> o1.getAge()-o2.getAge())
//                .forEach(e -> System.out.println(e.toString()));

        // 改写成写好排序的CopareByAgeAsc()静态方法  第三步
//        objects.stream().sorted((o1, o2) -> CompareByAge.CopareByAgeAsc(o1, o2))
//                .forEach(e -> System.out.println(e.toString()));

        // 改写成静态方法引用  第四步
//        objects.stream().sorted(CompareByAge::CopareByAgeAsc)
//                .forEach(e -> System.out.println(e.toString()));

}

第二种适用情况

    @Test
    public void test1(){
        List objects = new ArrayList<>();
        Cat hei = new Cat("小黑", 11);
        Cat bai = new Cat("小白", 23);
        Cat lan = new Cat("小蓝", 45);
        Cat hong = new Cat("小红", 64);

        objects.add(hei);
        objects.add(bai);
        objects.add(lan);
        objects.add(hong);

        // 原本
//        objects.stream().sorted(new Comparator() {
//            @Override
//            public int compare(Cat o1, Cat o2) {
//                return o1.getAge()-o2.getAge();
//            }
//        }).forEach(e -> System.out.println(e.toString()));

        // 改写成lambda
//        objects.stream().sorted((o1, o2) -> o1.getAge()-o2.getAge())
//                .forEach(e -> System.out.println(e.toString()));

        // 改写成调用实例方法引用
        CompareByAge compareByAge = new CompareByAge();

//        objects.stream().sorted((o1, o2) -> compareByAge.CopareByAgeDesc(o1, o2))
//                .forEach(e -> System.out.println(e.toString()));

        // 改写成实例方法引用
        objects.stream().sorted(compareByAge::CopareByAgeDesc)
                .forEach(e -> System.out.println(e.toString()));

    }

第三种适用情况

    @Test
    public void test2(){

        String[] strings = new String[]{"banana","ahaaaa","fix","available"};

        // 原本
//        Arrays.sort(strings, new Comparator() {
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.compareTo(o2);
//            }
//        });

        // 改写成lambda
//        Arrays.sort(strings, (o1, o2) -> o1.compareTo(o2));

        // 改写成特定类型方法引用
        Arrays.sort(strings, String::compareTo);

        for (String string : strings) {
            System.out.println(string);
        }

    }

总结

        总的来说,Lambda表达式、Stream流和方法引用这些新特性都致力于简化代码,提高代码的可读性和可维护性。它们让我们能够以更加直观的方式处理和操作数据,减少了冗余的代码和中间变量的使用,使得代码更简洁、更易理解和调试。同时,它们还提供了更高效的数据处理方式,能够更好地应对大数据量和并行处理的场景。只有熟练使用后,就会非常顺手,也会觉得非常的香。举个我遇到的场景,要for遍历一个集合,然后又要根据集合中的字段做排序,去重等等操作,需要10+行的代码,使用这些新特性后,一行代码就搞定了,而且可读性也非常的高,一眼就能看出过滤的条件,去重等逻辑代码。

上述示例代码我都放在了gitee中,需要的伙伴可以自己拿。

你可能感兴趣的:(Java基础,java,开发语言)