Java8中stream对集合操作做了简化,用stream操作集合能极大程度简化代码。Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后就用尽了。

一、流的转换

  Java中的Stream的所有操作都是针对流的,所以,使用Stream必须要得到Stream对象。

  • 初始化stream流
    Stream stream = Stream.of("a", "b", "c");
  • 数组转换为stream流

    String [] strArray = new String[] {"a", "b", "c"};
    stream = Stream.of(strArray);
    或者
    stream = Arrays.stream(strArray);
  • 集合对象转换为一个stream流

    List<String> list = Arrays.asList(strArray);
    stream = list.stream();

二、流的基本操作

  •   遍历操作(map):使用map操作可以遍历集合中的每个对象,并对其进行操作,map之后,用.collect(Collectors.toList())会得到操作后的集合。
    //遍历转换为大写
    List<String> output = wordList.stream(). map(String::toUpperCase).collect(Collectors.toList());
    //平方数
    List<Integer> nums = Arrays.asList(1, 2, 3, 4);
    List<Integer> squareNums = nums.stream().map(n -> n * n).collect(Collectors.toList());
  • 过滤操作(filter):使用filter可以对象Stream中进行过滤,通过测试的元素将会留下来生成一个新的Stream。
    //去点空值
    List<String> filterLists = new ArrayList<>();
    filterLists.add("");
    filterLists.add("a");
    filterLists.add("b");
    List afterFilterLists = filterLists.stream().filter(s -> !s.isEmpty())
            .collect(Collectors.toList());
    
    //递归判断得到子数据
    private List<MenuDto> convertTree(List<MenuDto> menus,Long parentId) {
            List<MenuDto> targetList = new ArrayList<>();
            List<MenuDto> menuList = menus.stream().filter(item -> item.getParentId().equals(parentId)).collect(Collectors.toList());
            menuList.forEach(item ->{
                targetList.add(new MenuDto(item.getId(),
                        item.getUrl(),
                        item.getPath(),
                        item.getComponent(),
                        item.getName(),
                        item.getIconCls(),
                        item.getParentId(),
                        item.getEnabled(),
                        item.getSort(),
                        item.getRoles(),
                        convertTree(menus,item.getId()),
                        item.getMeta()));
            });
            //根据权重逆序
            List<MenuDto> targetList1=targetList.stream().sorted(Comparator.comparing(MenuDto::getSort).reversed()).collect(Collectors.toList());
            return targetList1;
        }
  • 循环操作(forEach):如果只是想对流中的每个对象进行一些自定义的操作,可以使用forEach。
    List<String> forEachLists = new ArrayList<>();
    forEachLists.add("a");
    forEachLists.add("b");
    forEachLists.add("c");
    
    forEachLists.stream().forEach(s-> System.out.println(s));
  • 返回特定的结果集合(limit/skip):limit 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素。
    //skip与limit是有顺序关系
    List<String> forEachLists = new ArrayList<>();
    forEachLists.add("a");
    forEachLists.add("b");
    forEachLists.add("c");
    forEachLists.add("d");
    forEachLists.add("e");
    forEachLists.add("f");
    List<String> limitLists = forEachLists.stream().skip(2).limit(3).collect(Collectors.toList());
  • 排序(sort/min/max/distinct):sort可以对集合中的所有元素进行排序。max,min可以寻找出流中最大或者最小的元素,而distinct可以寻找出不重复的元素。
    //对一个集合进行排序
    List<Integer> sortLists = new ArrayList<>();
    sortLists.add(1);
    sortLists.add(4);
    sortLists.add(6);
    sortLists.add(3);
    sortLists.add(2);
    List<Integer> afterSortLists = sortLists.stream().sorted((In1,In2)->
    
           In1-In2).collect(Collectors.toList());
    
    //自然序列
    List<Student> studentList1=studentList.stream().sorted().collect(Collectors.toList());
    //逆序
    List<Student> studentList2=studentList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
    //根据年龄自然顺序
    List<Student> studentList3=studentList.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
    //根据年龄逆序
    List<Student> studentList4=studentList.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());
    //打印
    studentList4.forEach(student -> System.out.println("id is "+student.getId()+" ;name is "+student.getName()+";age is "+student.getAge()));

    //得到其中长度最大的元素:
    List<String> maxLists = new ArrayList<>();
    maxLists.add("a");
    maxLists.add("b");
    maxLists.add("c");
    maxLists.add("d");
    maxLists.add("e");
    maxLists.add("f");
    maxLists.add("hahaha");
    int maxLength = maxLists.stream().mapToInt(s->s.length()).max().getAsInt();
    System.out.println("字符串长度最长的长度为"+maxLength);
    //对一个集合进行查重
    List<String> distinctList = new ArrayList<>();
    distinctList.add("a");
    distinctList.add("a");
    distinctList.add("c");
    distinctList.add("d");
    List<String> afterDistinctList = distinctList.stream().distinct().collect(Collectors.toList());
  • 匹配(Match方法):有的时候,我们只需要判断集合中是否全部满足条件,或者判断集合中是否有满足条件的元素,这时候就可以使用match方法:

    allMatch:Stream 中全部元素符合传入的 predicate,返回 true
    anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true

    noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true

    //判断集合中没有有为‘c’的元素
    List<String> matchList = new ArrayList<>();
    matchList.add("a");
    matchList.add("a");
    matchList.add("c");
    matchList.add("d");
    boolean isExits = matchList.stream().anyMatch(s -> s.equals("c"));
    
    //判断集合中是否全不为空
    List<String> matchList = new ArrayList<>();
    matchList.add("a");
    matchList.add("");
    matchList.add("a");
    matchList.add("c");
    matchList.add("d");
    boolean isNotEmpty = matchList.stream().noneMatch(s -> s.isEmpty());
02-13 23:37