Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >跨站数据

Java之Lambda使用(案例)

Lambda减少了我们很多行代码,好处多多,但是弊端也不少,所以大家根据场景适当使用。

优点与缺点

优点:

  1. 代码量减少,提升了开发效率
  2. 集合操作也得到了极大的改善
  3. 函数式编程是技术的发展方向,而Lambda时函数式编程最基础的内容,所以,Java8中加入Lambda表达式本身时符合技术发展方向的。
  4. 通过引入Lambda,最直观的一个改进是不用再写大量的匿名内部类,还有更多由于函数式编程本身特性带来的提升。比如:代码的可读性会更好,高阶函数引入了函数组合的概念。
  5. Lambda的引入,集合操作也得到了极大的改善。比如:引入Stream API,把map,reduce,filter这样的基本函数式编程的概念与Java集合结合起来。在大多数情况下,处理集合时,Java程序员可以告别for,while,if这些语句,map,reduce,filter等操作都可以并行化,在一些条件下,可以提升性能。

缺点:

  1. 可读性差,与啰嗦的但是清晰的匿名类代码结构比较起来,Lambda表达式一旦变得比较长,就难以理解。
  2. 不便于调试,很难在Lambda表达式中增加调试信息,比如日志。
  3. 版本支持,Lambda表达式在JDK8版本中才开始支持,如果系统使用的是以前的版本,考虑系统的稳定性等原因,而不愿意升级,那么就无法使用。

使用场景

Lambda比较适合用在简短的业务代码中,并不适合用在复杂的系统中,会加大维护成本。

开始使用

以下代码中的各种方法,是我在开发过程中经常使用的方法,还有很多我没有用到,如果有其它香香的方法,欢迎提出。

private void testLambda() {
        Person p1 = new Person("a a", 11);
        Person p2 = new Person("b b", 12);
        Person p3 = new Person("c c", 13);
        Person p4 = new Person("d d", 14);
        Person p5 = new Person("e e", 15);
        List<Person> list = Arrays.asList(p1, p2, p3, p4, p5);

        /*
         * 集合去重(过滤条件)
         * temp: 临时集合,用来暂存集合中的值
         * repeat: 存在重复值得集合(需要去重的集合)
         * return: [1, 2, 3, 4]
         */
        List<String> temp = new ArrayList<>();
        List<String> repeat = Arrays.asList("1", "1", "2", "2", "3", "4", "4");
        System.out.println(repeat.stream().filter(p -> {
            boolean flag = !temp.contains(p);
            temp.add(p);
            return flag;
        }).collect(Collectors.toList()));

        /*
         * 过滤条件后返回新的集合
         * result: [Person(name=d d, age=14), Person(name=e e, age=15)]
         */
        System.out.println(list.stream().filter(p -> (p.getAge() > 13)).collect(Collectors.toList()));

        /*
         * List中每个对象的指定属性,赋值给另外一个对象,再添加到新的集合中
         * result: [PersonVo(code=a a, value=11), PersonVo(code=b b, value=12), PersonVo(code=c c, value=13), PersonVo(code=d d, value=14), PersonVo(code=e e, value=15)]
         */
        System.out.println(list.stream().map(p -> new PersonVo(p.getName(), p.get
        /*
         * List中的对象和vo对象如果Age())).collect(Collectors.toList()));有相同字段,用如下方法,可以复制List中所有对象给新的List集合中
         * 前提是两个List集合中的对象存在相同的属性值,否则新的List集合中的所有对象的所有属性值都为null
         * result: [Person(name=d d, age=14), Person(name=e e, age=15), ...]
         */
        System.out.println(list.stream().map(p -> {
            PersonVo vo = new PersonVo();
            BeanUtils.copyProperties(p, vo);
            return vo;
        }).collect(Collectors.toList()));
        /*
         * List中每个对象的指定属性(单个),添加到新的集合中
         * result: [a a, b b, c c, d d, e e]
         */
        System.out.println(list.stream().map(Person::getName).collect(Collectors.toList()));
        /*
         * 根据List中每个对象的指定属性进行(正序)排序,返回新的集合
         * result: [Person(name=a a, age=11), Person(name=b b, age=12), Person(name=c c, age=13), Person(name=d d, age=14), Person(name=e e, age=15)]
         */
        System.out.println(list.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList()));
        /*
         * 根据List中每个对象的指定属性进行(倒序)排序,返回新的集合
         * result: [Person(name=e e, age=15), Person(name=d d, age=14), Person(name=c c, age=13), Person(name=b b, age=12), Person(name=a a, age=11)]
         */
        System.out.println(list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList()));
        /*
         * List中每个对象的指定属性进行分割后所得到的字符串全部添加到新的集合中
         * result: [a, a, b, b, c, c, d, d, e, e]
         */
        System.out.println(list.stream().flatMap(p -> Arrays.stream(p.getName().split(" "))).collect(Collectors.toList()));
        /*
         * 将List转为Map,自定义key或value
         * result: {a a=11, b b=12, c c=13, d d=14, e e=15}
         */
        System.out.println(list.stream().collect(Collectors.toMap(Person::getName, Person::getAge)));
        /*
         * 将List转为Map, value -> value,后面的value指的是该对象
         * result: {a a=Person(name=a a, age=11), b b=Person(name=b b, age=12), c c=Person(name=c c, age=13), d d=Person(name=d d, age=14), e e=Person(name=e e, age=15)}
         */
        System.out.println(list.stream().collect(Collectors.toMap(Person::getName, value -> value)));
        /*
         * 根据List中对象的某个属性是否符合自定义条件进行分组
         * result: {false=[Person(name=a a, age=11), Person(name=b b, age=12), Person(name=c c, age=13), Person(name=e e, age=15)], true=[Person(name=d d, age=14)]}
         */
        System.out.println(list.stream().collect(Collectors.groupingBy(p -> "d d".equals(p.getName()))));
        /*
         * 将List中对象的某个属性提取出来,用指定字符拼接,并将拼接后的字符串添加前缀和后缀
         * result: {a a,b b,c c,d d,e e}
         */
        System.out.println(list.stream().map(Person::getName).collect(Collectors.joining(",", "{", "}")));
        
    }

性能

多线程的情况下,lambda比for循环效率要高
单线程的情况下,for循环比lambda效率要高

除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog

上一篇: Vue首次加载不触发watch的解决方法

下一篇: 使用JdbcTemplate查询PostgreSQL的所有表

精华推荐