当前位置: 首页 > 图灵资讯 > 技术篇> Java8之Stream的学习

Java8之Stream的学习

来源:图灵教育
时间:2023-06-04 09:10:23

一、理解概念

Stream可由数组或集合创建,对流操作可分为两种:

  1. 中间操作,每次回到一个新的流,可以有多个。
  2. 终端操作,每个流只能进行一次终端操作,终端操作结束后流不能再使用。终端操作会产生新的集合或值。
二、创建Stream

public class StreamDemo {    public static void main(String[] args) {        // 集合        List<Integer> list = Arrays.asList(1, 2, 3);        // 集合创建顺序流        Stream<Integer> stream = list.stream();        // 集合创建并行流        Stream<Integer> parallelStream = list.parallelStream();          // 数组        int[] array = {1, 3, 5, 6, 8};        // 数组创建流动模式        IntStream intStream = Arrays.stream(array);            }}

stream和paralelstream的简单区别:stream是顺序流,由主线程按顺序对流操作,而paralelstream是并行流,内部以多线程并行执行的方式对流操作,但前提是流中的数据处理没有顺序要求。

三、方法学习1、遍历/匹配(foreach/find/match)

import java.util.*; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);        // foreach        list.forEach(System.out::println);         System.out.println("----------");         //find        Optional<Integer> firstData = list.stream().findFirst();        System.out.println(firstData.get());         System.out.println("----------");         //match: AnyMatch有匹配,返回true nonematch返回true没有任何匹配 所有匹配的allmatch返回true        System.out.println(list.stream().anyMatch(x -> x > 4));    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, 3000.0));        employeeList.add(new Employee(李四), 18, 5000.0));        employeeList.add(new Employee(王五”, 28, 7000.0));        employeeList.add(new Employee(孙六), 38, 9000.0));        return employeeList;    }}

显示执行程序控制台

12345----------1----------true

2、根据条件匹配filter

import java.util.*;import java.util.stream.Collectors; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Employee> employeeList = initEmployee();        // 筛选18岁以上的员工        List<Employee> employees = employeeList.stream().filter(s -> s.getAge() > 18).collect(Collectors.toList());        System.out.println(employees);    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, 3000.0));        employeeList.add(new Employee(李四), 18, 5000.0));        employeeList.add(new Employee(王五”, 28, 7000.0));        employeeList.add(new Employee(孙六), 38, 9000.0));        return employeeList;    }}

显示执行程序控制台

[Employee{name='王五', age=28, salary=7000.0}, Employee{name='孙六', age=38, salary=9000.0}]

3、聚合max、min、count

import java.util.*; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Employee> employeeList = initEmployee();        // 工资最高的员工        Optional<Employee> employeeOptional = employeeList.stream().max(Comparator.comparing(Employee::getSalary, Double::compareTo));        System.out.println(employeeOptional.get());         // 获得年级最小的员工        Optional<Employee> employeeoptional = employeeList.stream().min(Comparator.comparing(Employee::getAge, Integer::compareTo));        System.out.println(employeoptional.get());         // 18年级以上的员工数量        long count = employeeList.stream().filter(s -> s.getAge() > 18).count();        System.out.println(count);    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, 3000.0));        employeeList.add(new Employee(李四), 18, 5000.0));        employeeList.add(new Employee(王五”, 28, 7000.0));        employeeList.add(new Employee(孙六), 38, 9000.0));        return employeeList;    }}

执行程序后,控制台显示

Employee{name='孙六', age=38, salary=9000.0}Employee{name='张三', age=8, salary=3000.0}2

4、map与flatMap 数据转换与数据合并

/** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<String> list = Arrays.asList("a","b","c");        // 将小写字母转换为map中的大写字母        List<String> stringList = list.stream().map(String::toUpperCase).collect(Collectors.toList());        // 输出[A, B, C]        System.out.println(stringList);    }}

/** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        String[] arr = {"z-h-a-n-g", "s-a-n"};        List<String> list = Arrays.asList(arr);        System.out.println(list);        // 将两个字符数组合成新的字符数组        List<String> collect = list.stream().flatMap(x -> {            String[] array = x.split("-");            return Arrays.stream(array);        }).collect(Collectors.toList());        System.out.println(collect);    }}

flatmap将两个数据流合并为数据流

[z-h-a-n-g, s-a-n][z, h, a, n, g, s, a, n]

5、规定reduce

合同,又称缩减,顾名思义,就是将一个流缩减为一个值,可以实现集合求和、乘积和最值操作。

import java.util.*; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Employee> list = initEmployee();        // 要求所有工资的和        Double sum = list.stream().map(Employee::getSalary).reduce(0.0, Double::sum);        System.out.println(sum);         // 求职者工资最大值        Optional<Double> max = list.stream().map(Employee::getSalary).reduce((a, b) -> a > b ? a : b);        System.out.println(max.get());    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, 3000.0));        employeeList.add(new Employee(李四), 18, 5000.0));        employeeList.add(new Employee(王五”, 28, 7000.0));        employeeList.add(new Employee(孙六), 38, 9000.0));        return employeeList;    }}

执行程序后,控制台显示

24000.09000.0

6、数据收集(toList、toSet、toMap)

import java.util.*;import java.util.stream.Collectors; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Employee> list = initEmployee();        // 作为key返回名称,作为valuemap数据的工资        Map<String, Double> employeeMap = list.stream().collect(Collectors.toMap(Employee::getName, Employee::getSalary));        System.out.println(employeeMap);         // 职工名称集合        List<String> employeeNameList = list.stream().map(Employee::getName).collect(Collectors.toList());        System.out.println(employeeNameList);         // 职工年龄集合        Set<Integer> ageSet = list.stream().map(s -> s.getAge()).collect(Collectors.toSet());        System.out.println(ageSet);    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, 3000.0));        employeeList.add(new Employee(李四), 18, 5000.0));        employeeList.add(new Employee(王五”, 28, 7000.0));        employeeList.add(new Employee(孙六), 38, 9000.0));        return employeeList;    }}

执行程序后,控制台显示

{李四=5000.0, 张三=3000.0, 王五=7000.0, 孙六=9000.0}[张三, 李四, 王五, 孙六][18, 38, 8, 28]

7、collect

Collectors为数据统计提供了一系列静态方法:

Collectors为数据统计提供了一系列静态方法:

计数:count

平均值:averagingInt、averagingLong、averagingDouble

最值:maxBy、minBy

求和:summingInt、summingLong、summingDouble

统计以上一切:summarizingInt、summarizingLong、summarizingDouble

import java.util.*;import java.util.stream.Collectors; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Employee> employeeList = initEmployee();         // 统计员工人数        Long count = employeeList.stream().collect(Collectors.counting());        System.out.println(count);         // 获得员工最高工资        Optional<Double> salaryOptional = employeeList.stream().map(Employee::getSalary).collect(Collectors.maxBy((s1, s2) -> s1.compareTo(s2)));        System.out.println(salaryOptional);         // 获得员工平均工资        Double averageSalary = employeeList.stream().collect(Collectors.averagingDouble(Employee::getSalary));        System.out.println(averageSalary);         ///一次性统计员工全部工资信息        DoubleSummaryStatistics summaryStatistics = employeeList.stream().collect(Collectors.summarizingDouble(Employee::getSalary));        System.out.println(summaryStatistics);    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, 3000.0));        employeeList.add(new Employee(李四), 18, 5000.0));        employeeList.add(new Employee(王五”, 28, 7000.0));        employeeList.add(new Employee(孙六), 38, 9000.0));        return employeeList;    }}

执行程序后,控制台显示

4optional[9000.0]6000.0DoubleSummaryStatistics{count=4, sum=24000.000000, min=3000.000000, average=6000.000000, max=9000.000000}

8、分组(partitioningBy/groupingBy)

import java.util.*;import java.util.stream.Collectors; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Employee> employeeList = initEmployee();         // 员工的工资是否超过7000分组        Map<Boolean, List<Employee>> map = employeeList.stream().collect(Collectors.partitioningBy(s -> s.getSalary() > 7000));        System.out.println(map);         // 根据性别对员工进行分组        Map<String, List<Employee>> employeeMap = employeeList.stream().collect(Collectors.groupingBy(Employee::getSex));        System.out.println(employeeMap);    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, "男", 3000.0));        employeeList.add(new Employee(李四), 18, "女", 5000.0));        employeeList.add(new Employee(王五”, 28, "男", 7000.0));        employeeList.add(new Employee(孙六), 38, "女", 9000.0));        return employeeList;    }}

{false=[Employee{name='张三', age=8, salary=3000.0}, Employee{name='李四', age=18, salary=5000.0}, Employee{name='王五', age=28, salary=7000.0}], true=[Employee{name='孙六', age=38, salary=9000.0}=[Employee{name='李四', age=18, salary=5000.0}, Employee{name='孙六', age=38, salary=9000.0}], 男=[Employee{name='张三', age=8, salary=3000.0}, Employee{name='王五', age=28, salary=7000.0}]}

9、数据拼接joining

joining可以将stream中的元素与特定的连接符(如果没有,则直接连接)连接成字符串。

import java.util.*;import java.util.stream.Collectors; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Employee> employeeList = initEmployee();         // 将员工姓名拼接回逗号        String nameData = employeeList.stream().map(Employee::getName).collect(Collectors.joining(","));        System.out.println(nameData);    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, "男", 3000.0));        employeeList.add(new Employee(李四), 18, "女", 5000.0));        employeeList.add(new Employee(王五”, 28, "男", 7000.0));        employeeList.add(new Employee(孙六), 38, "女", 9000.0));        return employeeList;    }}

张三、李四、王五、孙六

10、sorted排序

import java.util.*;import java.util.stream.Collectors; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        List<Employee> employeeList = initEmployee();         // 对员工工资的升级进行排序        List<Employee> employees = employeeList.stream().sorted(Comparator.comparing(Employee::getSalary)).collect(Collectors.toList());        System.out.println(employees);         // 将员工工资降级排序        List<Employee> list = employeeList.stream().sorted(Comparator.comparing(Employee::getSalary).reversed()).collect(Collectors.toList());        System.out.println(list);    }     /**     * 初始化员工列表数据     */    private static List<Employee> initEmployee() {        List<Employee> employeeList = new ArrayList<>();        employeeList.add(new Employee(张三), 8, "男", 3000.0));        employeeList.add(new Employee(李四), 18, "女", 5000.0));        employeeList.add(new Employee(王五”, 28, "男", 7000.0));        employeeList.add(new Employee(孙六), 38, "女", 9000.0));        return employeeList;    }}

[Employee{name='张三', age=8, salary=3000.0}, Employee{name='李四', age=18, salary=5000.0}, Employee{name='王五', age=28, salary=7000.0}, Employee{name='孙六', age=38, salary=9000.0}][Employee{name='孙六', age=38, salary=9000.0}, Employee{name='王五', age=28, salary=7000.0}, Employee{name='李四', age=18, salary=5000.0}, Employee{name='张三', age=8, salary=3000.0}]

11、提取/组合(distinct/limit/skip)

import java.util.*;import java.util.stream.Collectors;import java.util.stream.Stream; /** * @author qinxun * @date 2023-06-02 * @Descripion: 职工测试类 */public class EmployeeDemo {    public static void main(String[] args) {        String[] arr1 = {"a", "b", "c", "d"};        String[] arr2 = {"d", "e", "f", "g"};        Stream<String> stream1 = Stream.of(arr1);        Stream<String> stream2 = Stream.of(arr2);         // 合并流        List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());        System.out.println(newList);         // 限制从流中获得前一个数据        System.out.println(Stream.of(arr1).limit(1).collect(Collectors.toList()));         // 跳过前两个数据        System.out.println(Stream.of(arr1).skip(2).collect(Collectors.toList()));    }}

[a, b, c, d, e, f, g][a][c, d]