Java8 lambda Stream常用语法

1,420 阅读2分钟

概述

Stream 作为 Java 8 的一大亮点,一个高级的迭代器(Iterator),数据只能遍历一次,用于简化代码。 下述几种工作常用的stream

Java 8 中的 Streams API 详解

常用方法

  • map 单组映射
  • flatmap 多组映射
  • filter 过滤
  • Collect 收集
  • groupingBy 分组
  • sort 排序
  • reduce 求和
  • distinct

获取对象值的方法

1. AClass::getField
2. o->o.getField()
3.  o->{
   return o.getField 
 }

Stream结果数据处理

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。Optional 类的引入很好的解决空指针异常。

Optional可以被collect收集出多个,也可以被findFirst收集出一个

        List<String> names2 = list.stream().map(o->o.getName()).collect(Collectors.toList());
        String name3 = list.stream().map(o->o.getName()).findFirst().orElse(null);

具体操作

map 映射

有人说这个是归类,但其实没到归类这一步,只是一种映射规则,你可以映射出一个基本类型、也可以映射出一个自定义对象。

        List<User> list = new ArrayList<>();
        list.add(new User(1,"zhangsan"));
        list.add(new User(2,"lisi"));

        List<String> names = list.stream().map(User::getName).collect(Collectors.toList());
        List<String> names2 = list.stream().map(o->o.getName()).collect(Collectors.toList());

filter 过滤条件

filter中可以写多个条件 用&& 或者|| 连接,只需要最终是一个boolean类型的值

        List<User> list = new ArrayList<>();
        list.add(new User(1,"zhangsan"));
        list.add(new User(2,"lisi"));

        List<User> names = list.stream().filter(o->o.getId()>1).collect(Collectors.toList());

groupingBy 分组

  • 按对象一个字段分组
        List<User> list = new ArrayList<>();
        list.add(new User(1,"zhangsan"));
        list.add(new User(2,"lisi"));
        Map<String, List<User>> collect = list.stream().collect(Collectors.groupingBy(User::getName));
  • 按对象中多个字段分组 需要先新建对象,然后重写UserGrouping的hashCode和equal
List<User> list = new ArrayList<>();
        list.add(new User(1,"zhangsan",10));
        list.add(new User(2,"lisi",10));
        Map<UserGrouping, List<User>> collect = list.stream()
                .collect(
                        Collectors.groupingBy(
                                o->new UserGrouping(o.getName(),o.getAge())
                                )
                        );

sorted 排序

  • 按对象一个字段排序
        List<User> list = new ArrayList<>();
        list.add(new User(1,"zhangsan",10));
        list.add(new User(2,"lisi",10));
        list.stream().sorted(Comparator.comparing(User::getName)).collect(Collectors.toList());
  • 按对象多个字段排序
        List<User> list = new ArrayList<>();
        list.add(new User(1,"zhangsan",10));
        list.add(new User(2,"lisi",10));
        list.stream().sorted(Comparator.comparing(User::getName)).collect(Collectors.toList());
        list.stream().sorted(
                Comparator.comparing(User::getName,(x,y)->{
                    if(x == null && y != null){
                        return 1;
                    }else if(x !=null && y == null){
                        return -1;
                    }else if(x == null && y == null){
                        return -1;
                    }else{
                    }
                    return 0;
                }
                )
                .thenComparing(Comparator.comparing(User::getAge))
                ).collect(Collectors.toList());
  • 但是我觉得可以用原本List的sort
list.sort(new Comparator<User>(){
            @Override
            public int compare(User o1, User o2) {
                if (o1.getAge()>o2.getAge()) {
                    return o1.getAge()-o2.getAge();
                } else if (o1.getAge()==o2.getAge()) {
                    if (o1.getName().hashCode()>o2.getName().hashCode()) {
                        return 1;
                    }
                }
                return 0;
            }
            
        });

distinc

  1. 去重,根据hashCode和equal去重。
List<User> userList = list.stream().distinct().collect(Collectors.toList());
  1. 根据特定的字段去重复
    List<User> collect = users.stream().collect(Collectors.collectingAndThen(
        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getUserName()))),
    ArrayList::new));

但是这种就不能根据多个字段去重复,如果要根据多个字段去重复应该用对象的形式把hashCode和equal写好,然后用第一种方式去重

flatMap

扁平化映射

    Map<String ,List<User>> map = new HashMap<>();
    Set<Entry<String, List<User>>> entrySet = map.entrySet();
    ist<User> collect = entrySet.stream().flatMap(o->o.getValue().stream())).collect(Collectors.toList());

利用Collect做List转Map

List<User> list = new ArrayList<>();
    Map<String, User> oldDetailMap = list.stream().collect(
            Collectors.toMap(detail -> detail.getCode(),
                    Function.identity(), (key1, key2) -> key2));
去重复
 Map<Integer, Student> map = list.stream().collect(Collectors.toMap(Student::getId, student -> student,(v1,v2)->v1));

list To map 去重复

Map<Long, User> collect = listAll.stream() .collect(Collectors.toMap(o -> o.getid(), Function.identity(), (o, n) -> o));