102-java8新特性(2)-Stream流

Stream流

102-java8新特性(2)-Stream流_第1张图片

一.概念

1.什么是Stream流?

Stream是数据渠道,用于操作数据源(集合.数组等)所产生的元素序列. 集合讲的是数据,流看中计算!!

2.注意事项

  1. Stream 自己不会存储元素
  2. Stream 不会改变源对象,他只会返回一个持有操作结果的新Stream.
  3. Stream 操作时延迟操作,这意味着他们会等到需要结果的时候才执行.

二.Stream的操作步骤

第一步 : 创建 Stream

一个数据源(集合,数组),获取一个Stream流,获取Stream流的方式有四种:

  • 集合 ==> Stream流
    collection 系列集合提供的stream() 或者parallelStream()
 		//1.collection 系列集合提供的stream() 或者parallelStream()
        ArrayList<String> strings = new ArrayList<>();
        Stream<String> stream = strings.stream();
  • 将数组 ==> Stream流
    通过Arrays 中的静态方法 stream()获取数组流
		List<Employee> employees = Arrays.asList(
            new Employee(1,"张三",13,12000.0),
            new Employee(2,"李四",88,4200.0),
            new Employee(3,"王五",23,3200.0),
            new Employee(4,"赵六",5,1500.0),
            new Employee(5,"田七",55,888.0),
            new Employee(6,"古八",8,3000.0),
            new Employee(6,"古八",8,3000.0)
    );
		//2.通过Arrays 中的静态方法 stream()获取数组流
        Employee[] employees = new Employee[10];
        Stream<Employee> employeeStream = Arrays.stream(employees);
  • 将一对类型相同的数据 ==> Stream流
    通过 Stream 类中的静态方法 of()
		//3.通过 Stream 类中的静态方法 of()
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
  • 创建无限流
    (1)迭代方式创建无限流
//4.1 迭代
        Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 1);
        iterate.limit(4).forEach(System.out::println);
  • (2)生成方式创建无限流
 //4.2 生成
        Stream<Double> generate = Stream.generate(() -> Math.random());
        generate.limit(5).forEach(System.out::println);

第二步 : 中间操作

一个中间操作链,对数据源的数据进行处理
中间操作分为以下几类:

1.筛选与切片(减少数据)
  • filter --过滤元素
 		//filter 过滤
       employees.stream()
            .filter((x) -> x.getAge() > 10) //filter 中的参数是predicate接口类型,即 ==> boolean test(T t);
               .forEach(System.out::println); //forEach 中的参数是consumer类型的,即 ==> void accept(T t);
  • limit – 限制元素数量
		 //limit 限制
        employees.stream()
                .filter(x -> x.getSalary() > 2000) //filter 过滤
                .limit(3) //限制3条记录
                .forEach(x -> System.out.println("limit结果:" + x));
  • skip(n) – 跳过元素,返回一个扔掉了前n个元素的路,若流中元素不足n个,则返回一个空流.与limit互补
		//skip(n) 跳过
        employees.stream()
                .skip(3) //跳过前三个
                .filter(x -> x.getSalary() > 1000.0) //过滤
                .forEach(x -> System.out.println("skip结果:" +  x));
  • distinct – 去除重复的元素
 		//distinct 去重
        employees.stream()
                .filter(x -> x.getId() > 2)
                .distinct() //去重比较的是hashcode方法和equals方法
                .forEach(x -> System.out.println("distinct:" + x));

2.映射(映射修改数据)
  • map – 将流中的元素转换成其他值
		//demo1 将集合中的元素,全部转为大写
        List<String> strings = Arrays.asList("a", "b", "c", "d", "E");
        strings.stream()
                .map(str -> str.toUpperCase()) //接收一个Function参数 ==> R apply(T t);
                .forEach(System.out::println);

        System.out.println("============================");

        //demo2
        employees.stream()
                .map(e -> e.getName()) //将每一个employee元素转换成employee中的name
                .forEach(System.out::println);

        System.out.println("============================");
  • flatMap – 将流中的每个元素转换成另外一个流,并将这些数,添加到流中,类似于集合的addAll()方法
3.排序(对元素值进行排序)
  • sorted() – 自然排序(Comparable)
		//demo1 自然排序
        List<String> strings = Arrays.asList("a", "d", "e", "c", "b");
        strings.stream()
                .sorted()
                .forEach(System.out::println);
  • sorted(Comparator com) – 定制排序(Comparator)
		//demo2  定制排序
        employees.stream()
                .sorted((e1,e2) -> {
     
                    if(e1.getAge() == e2.getAge()){
     
                        return e1.getName().compareTo(e2.getName());
                    }else {
     
                        return Integer.compare(e1.getAge(),e2.getAge());
                    }
                }).forEach(System.out::println);

第三步 : 终止操作(终端操作)

1.匹配 (返回的boolean)

  • allMatch 是否全部比配
 		//allMatch 是否年龄都大于10岁
        boolean allMatch = employees.stream()
                .allMatch(e -> e.getAge() > 10);
        System.out.println("所有的员工是否年龄都大于10岁:" + allMatch);
  • anyMatch 是否至少匹配一个
		 //anyMatch 查找是否有一个人的名字叫古八的
        boolean anyMatch = employees.stream()
                .anyMatch(e -> e.getName().equals("古八")); //查找是否有一个人的名字叫古八的
        System.out.println("查找是否有一个人的名字叫古八:" + anyMatch);
  • noneMatch 是否都不匹配
 		//noneMatch 判断是不是没有人的工资高于20000
        boolean noneMatch = employees.stream()
                .noneMatch(e -> e.getSalary() > 20000); //判断是不是没有人的工资高于20000
        System.out.println("判断是不是没有人的工资高于20000:" + noneMatch);

2.查找

  • findFirst 返回第一个元素
  • findAny 返回任意一个
  • count 返回数量
  • max 返回流中的最大值
  • min 返回流中的最小值
  • forEach 循环流中所有元素
		//findFirst 获取年龄最小的员工
        //optional优点类似于如果当前元素为空,则用null代替
        Optional<Employee> first = employees.stream()
                .sorted((e1, e2) -> {
     
                    if (e1.getAge() == e2.getAge()) {
     
                        return e1.getName().compareTo(e2.getName());
                    } else {
     
                        return Integer.compare(e1.getAge(), e2.getAge());
                    }
                }).findFirst();
        System.out.println("年龄最小的员工是:" + first);

        System.out.println("================");
        
        //count计数
        long count = employees.stream()
                .filter(e -> e.getSalary() > 3000)
                .count();
        System.out.println("工资大于3000的员工的数量:" + count);

        System.out.println("=====================");
        
        //max 年龄最大的员工的年龄是
        Optional<Integer> maxAge = employees.stream()
                .map(e -> e.getAge())
                .max((e1, e2) -> Integer.compare(e1, e2));
        System.out.println("员工中年龄最大为:" + maxAge);

3.规约(可以做统计)

  • T reduce(T identity, BinaryOperator accumulator); //指定初始值,计算
  • Optional reduce(BinaryOperator accumulator); //不指定初始值计算
		List<Integer> list = Arrays.asList(1, 2, 4, 5, 6, 7, 8);
        Integer reduce = list.stream()
                //参数1 : 表示x的起始值,以后x的值等于x和集合中的每个元素计算得来的值;
                //参数2 : 表示每一个流中的元素
                .reduce(2, (x, y) -> x + y);
        System.out.println(reduce);

        System.out.println("====================");
        Optional<Double> reduce1 = employees.stream()
                .map(Employee::getSalary) //将流中的employee元素映射为工资元素
                .reduce(Double::sum); //并且对工资求和
        System.out.println(reduce1);

4.收集

  • 转换为其他的数据类型
		//demo1  将所有的employee的员工姓名收集到一个集合中去
        List<String> list = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());//去重复收集,因为是收集到set集合中去
        list.forEach(System.out::println);

        System.out.println("=========================");
        //demo2  将所有的employee的员工姓名收集到一个集合中去
        Set<String> set = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());//收集到list集合中去
        set.forEach(System.out::println);

        System.out.println("=========================");
        //demo3  将所有的employee的员工姓名收集到一个集合中去
        HashSet<String> hashSet = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));//收集到Hashset集合中去
        hashSet.forEach(System.out::println);
  • 先做计算
//count 统计
        Long count = employees.stream()
                .collect(Collectors.counting());
        System.out.println("员工总数:" + count);

        //工资平均值
        Double ave = employees.stream()
                .collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println("工资平均数:" + ave);

        System.out.println("====================");
        //工资总和
        DoubleSummaryStatistics sum = employees.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println("工资总和:" + sum.getSum());
        System.out.println("工资平均数:" + sum.getAverage());
        System.out.println("统计数目:" + sum.getCount());
        System.out.println("工资最高的:" + sum.getMax());
        System.out.println("工资最低的:" + sum.getMin());
        System.out.println("====================");

        //工资最大值
        Optional<Double> max = employees.stream()
                .map(Employee::getSalary)
                .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1, e2)));
        System.out.println("工资最高:" + max);

        //年龄最小值
        Optional<Integer> min = employees.stream()
                .map(Employee::getAge)
                .collect(Collectors.minBy((e1, e2) -> Integer.compare(e1, e2)));
        System.out.println("年龄最小的为多少岁:" + min);
  • 分组
		Map<String, List<Employee>> map = employees.stream()
                .collect(Collectors.groupingBy((e) -> {
      //分组,按照年龄分组;小于30的为青少年;30-60的为中年;60以上为老年
                    if (((Employee) e).getAge() < 30) {
     
                        return "青少年";
                    } else if (((Employee) e).getAge() < 60) {
     
                        return "中年";
                    } else {
     
                        return "老年";
                    }
                }));

        for (String s : map.keySet()) {
     
            List<Employee> employees = map.get(s);
            System.out.println(s + ":" + employees);
        }
  • 分区
 		Map<Boolean, List<Employee>> map = employees.stream()
                .collect(Collectors.partitioningBy((x) -> x.getSalary() > 3000)); //分区,工资大于3000的是一个区,工资小于等于3000的是一个区
        for (Boolean aBoolean : map.keySet()) {
     
            System.out.println(aBoolean + ":" + map.get(aBoolean));
        }

你可能感兴趣的:(javase,java,8新特性)