.._.stream().map">
赞
踩
Java8 Stream 思维导图
目录
2.6.3分组(partitioningBy/groupingBy)
方式一:通过 java.util.Collection.stream() 方法用集合创建流
- /**
- * 创建方式一:通过 java.util.Collection.stream() 方法用集合创建流
- */
- List<String> list = Arrays.asList("a", "b", "c", "d");
-
- // 创建一个顺序流
- Stream<String> stream = list.stream();
- stream.forEach(System.out::println);
-
- // 创建一个并行流
- Stream<String> parallelStream = list.parallelStream();
- parallelStream.forEach(System.out::println);
方式二:通过java.util.Arrays.stream(T[] array)方法用数组创建流
- int[] array = {1,2,3,4,5,6};
- IntStream intStream = Arrays.stream(array);
- intStream.forEach(System.out::println);
方式三:通过Stream的静态方法:of()、iterate()、generate()
- Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
- integerStream.forEach(System.out::println);
-
- Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
- stream2.forEach(System.out::println);
-
- Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
- stream3.forEach(System.out::println);
stream和parallelStream区分:
1、stream是顺序流,由主线程按顺序对流执行操作。
2、parallelStream是并行流,内部以多线程并行执行的方式对流进行操作,前提是流中的数据处理没有顺序要求。
运行流程图说明:
知识点拓展:
通过parallel()把顺序流转换成并行流。
员工类实体定义:
- package com.zzg.entity;
-
- import java.io.Serializable;
-
- import lombok.AllArgsConstructor;
- import lombok.Builder;
- import lombok.Data;
- import lombok.NoArgsConstructor;
-
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- @Builder
- @SuppressWarnings("serial")
- public class Person implements Serializable {
- private String name; // 姓名
- private int salary; // 薪资
- private int age; // 年龄
- private String sex; //性别
- private String area; // 地区
- }
Stream
支持类似集合的遍历和匹配元素。
- /**
- * 温馨提示:Stream中的元素是以Optional类型存在
- */
-
- // List<Integer> list = Arrays.asList(1,2,3,4,5);
- List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
-
- /**
- * 遍历输出符合条件的元素
- */
- list.stream().filter(x -> x > 6).forEach(System.out::println);
- /**
- * 输出符合条件的第一个元素
- */
- Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
- /**
- * 输出符合条件的任意元素(适用于并行流)
- */
- Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
- /**
- * 判断是否包含符合特定条件的元素
- */
- boolean anyMatch = list.stream().anyMatch(x -> x > 6);
- System.out.println("匹配第一个值:" + findFirst.orElse(0));
- System.out.println("匹配任意一个值:" + findAny.orElse(0));
- System.out.println("是否存在大于6的值:" + anyMatch);
筛选,按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。
- List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
- /**
- * 案例一:筛选出Integer集合中 大于8的元素,并打印出来
- */
- list.stream().filter(x -> x > 8).forEach(System.out::println);
-
- /**
- * 案例二:筛选薪资大于8000的员工名称,构建新的集合 温馨提示:map 用于获取指定对象的属性值 collect 用于构建新的集合
- */
- List<Person> dataList = init();
- List<String> names = dataList.stream().filter(item -> item.getSalary() > 8000).map(item -> item.getName())
- .collect(Collectors.toList());
- names.stream().forEach(System.out::println);
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
- return personList;
- }
对集合、数组的数据进行统计操作。
- /**
- * 案例三:获取员工集合中姓名字符串最长。
- */
- String name = dataList.stream().map(item -> item.getName()).collect(Collectors.toList()).stream()
- .max(Comparator.comparing(String::length)).orElse("");
- System.out.println("用户名称:" + name);
-
- /**
- * 案例四: 获取Integer 最大值
- */
- List<Integer> sortList = Arrays.asList(7, 6, 9, 4, 11, 6);
-
- // 自然排序
- Optional<Integer> max = sortList.stream().max(Integer::compareTo);
- // 自定义排序
- Optional<Integer> max2 = sortList.stream().max(new Comparator<Integer>() {
- @Override
- public int compare(Integer o1, Integer o2) {
- return o1.compareTo(o2);
- }
- });
- System.out.println("自然排序的最大值:" + max.orElse(0));
- System.out.println("自定义排序的最大值:" + max2.orElse(0));
-
- /**
- * 案例五: 获取员工集合中工资最高
- */
- Optional<Person> salary = dataList.stream().max(Comparator.comparingInt(Person::getSalary));
- /**
- * 基于lombok 创建模式构建Person 对象并赋值Salary 初始值
- */
- System.out.println("员工工资最大值:" + salary.orElse(Person.builder().salary(0).build()).getSalary());
-
- /**
- * 案例六:统计Integer集合中大于6的元素的个数
- */
- List<Integer> integerList = Arrays.asList(7, 6, 4, 8, 2, 11, 9);
- long integerCount = integerList.stream().filter(item -> item >= 6).count();
- System.out.println("integer 集合大于6个数:" + integerCount);
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
- return personList;
- }
映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map
和flatMap
:
map
:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。flatMap
:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。- /**
- * 案例七:遍历字符串列表,通过','逗号分隔符构建新列表
- */
- List<String> strList = Arrays.asList("A,B,C", "D,E,F");
- List<String> newStrList = strList.stream().flatMap(item -> {
- return Arrays.stream(item.split(","));
- }).collect(Collectors.toList());
- newStrList.stream().forEach(System.out::println);
实现对集合求和、求乘积和求最值操作
- /**
- * 案例八: 统计员工集合工资总数 温馨提示: 通过reduce 实现数值归纳总结,实现对集合求和、求乘积和求最值操作
- */
- Integer totalSalary = dataList.stream().map(Person::getSalary).collect(Collectors.toList()).stream()
- .reduce(Integer::sum).orElse(0);
- System.out.println("员工集合工资总数:" + totalSalary);
-
- /**
- * reduce 归纳统计使用匿名函数
- */
- Integer totalSalaryTwo = dataList.stream().map(Person::getSalary).collect(Collectors.toList()).stream()
- .reduce((x, y) -> x + y).orElse(0);
- System.out.println("员工集合工资总数:" + totalSalaryTwo);
-
- /**
- * reduce 归纳统计求最大值
- */
- Integer totalSalaryThree = dataList.stream().map(Person::getSalary).collect(Collectors.toList()).stream()
- .reduce(Integer::max).orElse(0);
- System.out.println("员工工资最高:" + totalSalaryThree);
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
- return personList;
- }
collect
就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。
collect
主要依赖java.util.stream.Collectors
类内置的静态方法。
- List<String> nameList = dataList.stream().map(Person::getName).collect(Collectors.toList());
- nameList.stream().forEach(System.out::println);
- Map<String, Person> mapNameObject = dataList.stream().collect(Collectors.toMap(Person::getName, item -> item));
- /**
- * java8 遍历map
- */
- mapNameObject.forEach((k, v) -> {
- System.out.println("员工姓名:" + k);
- System.out.println("toString():" + v.toString());
- });
-
- Set<Person> setObject = dataList.stream().collect(Collectors.toSet());
- /**
- * java8 遍历set
- */
- setObject.forEach(item -> {
- System.out.println("toString():" + item.toString());
- });
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
- return personList;
- }
Collectors提供了一系列用于数据统计的静态方法:
- // 求总数
- Long count = dataList.stream().collect(Collectors.counting());
- // 求平均工资
- Double average = dataList.stream().collect(Collectors.averagingDouble(Person::getSalary));
- // 求最高工资
- Optional<Integer> max3 = dataList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
- // 求工资之和
- Integer sum = dataList.stream().collect(Collectors.summingInt(Person::getSalary));
- // 一次性统计所有信息
- DoubleSummaryStatistics collect = dataList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
-
- System.out.println("员工总数:" + count);
- System.out.println("员工工资最高:" + max3);
- System.out.println("员工平均工资:" + average);
- System.out.println("员工工资总和:" + sum);
- System.out.println("员工工资所有统计:" + collect);
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
- return personList;
- }
stream
按条件分为两个Map
,比如员工按薪资是否高于8000分为两部分。- // 将员工按薪资是否高于8000分组
- Map<Boolean, List<Person>> part = dataList.stream()
- .collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
- // 将员工按性别分组
- Map<String, List<Person>> group = dataList.stream().collect(Collectors.groupingBy(Person::getSex));
- // 将员工先按性别分组,再按地区分组
- Map<String, Map<String, List<Person>>> group2 = dataList.stream()
- .collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
- System.out.println("员工按薪资是否大于8000分组情况:" + part);
- System.out.println("员工按性别分组情况:" + group);
- System.out.println("员工按性别、地区:" + group2);
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
- return personList;
- }
joining
将stream中的元素用特定的连接符连接成一个字符串。
- String nameJoin = dataList.stream().map(Person::getName).collect(Collectors.joining(","));
- System.out.println("拼接员工姓名:" + nameJoin);
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
- return personList;
- }
Collectors
类提供的reducing
方法,相比于stream
本身的reduce
方法,增加了对自定义归约的支持。
- Integer sum1 = dataList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j - 5000)));
- System.out.println("员工扣税薪资总和:" + sum1);
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
- return personList;
- }
sorted,排序操作。支持两种排序:
sorted():自然排序,流中元素需实现 Comparable 接口
sorted(Comparator com):Comparator 排序器自定义排序
- // 按工资升序排序(自然排序)
- List<String> newList = dataList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
- .collect(Collectors.toList());
- // 按工资倒序排序
- List<String> newList2 = dataList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
- .map(Person::getName).collect(Collectors.toList());
- // 先按工资再按年龄升序排序
- List<String> newList3 = dataList.stream()
- .sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
- .collect(Collectors.toList());
- // 先按工资再按年龄自定义排序(降序)
- List<String> newList4 = dataList.stream().sorted((p1, p2) -> {
- if (p1.getSalary() == p2.getSalary()) {
- return p2.getAge() - p1.getAge();
- } else {
- return p2.getSalary() - p1.getSalary();
- }
- }).map(Person::getName).collect(Collectors.toList());
-
- System.out.println("按工资升序排序:" + newList);
- System.out.println("按工资降序排序:" + newList2);
- System.out.println("先按工资再按年龄升序排序:" + newList3);
- System.out.println("先按工资再按年龄自定义降序排序:" + newList4);
- public static List<Person> init() {
- List<Person> personList = new ArrayList<Person>();
- personList.add(new Person("Tom", 8900, 25, "male", "New York"));
- personList.add(new Person("Jack", 7000, 21, "male", "Washington"));
- personList.add(new Person("Lily", 7800, 29, "female", "Washington"));
- personList.add(new Person("Anni", 8200, 31, "female", "New York"));
- personList.add(new Person("Owen", 9500, 35, "male", "New York"));
- personList.add(new Person("Alisa", 7900, 51, "female", "New York"));
流也可以进行合并、去重、限制、跳过等操作。
- String[] arr1 = { "a", "b", "c", "d" };
- String[] arr2 = { "d", "e", "f", "g" };
-
- Stream<String> stream1 = Stream.of(arr1);
- Stream<String> stream2 = Stream.of(arr2);
- // concat:合并两个流 distinct:去重
- List<String> newList1 = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
- // limit:限制从流中获得前n个数据
- List<Integer> collect1 = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
- // skip:跳过前n个数据
- List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
-
- System.out.println("流合并:" + newList1);
- System.out.println("limit:" + collect1);
- System.out.println("skip:" + collect2);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。