IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java8 Stream API -> 正文阅读

[Java知识库]Java8 Stream API

Stream的特点

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

Stream的三个操作步骤

  • 创建Stream
  • 中间步骤
  • 终止操作(终端操作)

1. 创建 Stream

最常用的是第一种方法

// 1.创建Stream
@Test
public void t1() {
    // 1.可以通过Collection系列集合提供的stream()或parallelStream()
    List<String> list = new ArrayList<>();
    Stream<String> stream1 = list.stream();

    // 2.通过Arrays中的静态方法stream()获取数组流
    Employee[] arr = new Employee[10];
    Stream<Employee> stream2 = Arrays.stream(arr);

    // 3.通过Stream类中的静态方法of()
    Stream<String> stream3 = Stream.of("aa", "bb", "cc", "dd");

    // 4.创建无限流
    // 迭代
    Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
    stream4.limit(10).forEach(System.out::println);
    // 生成
    Stream<Double> stream5 = Stream.generate(Math::random);
    stream5.limit(10).forEach(System.out::println);
}

2. Stream的中间操作

特点:多个中间操作可以连接起来形成一个流水线除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”

筛选与切片

  • filter:接收Lambda,从流中排除某些元素
  • limit:截断流 ,使其元素不超过给定数量
  • skip(n):跳过元素, 返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补
  • distinct:筛选, 通过流所生成元素的hashCode()equals()去除重复元素

测试数据:

List<Employee> employees = Arrays.asList(
        new Employee("张三", 18, 6999.9, Employee.Status.FREE),
        new Employee("李四", 38, 3999.9, Employee.Status.BUSY),
        new Employee("王五", 50, 5999.9, Employee.Status.VOCATION),
        new Employee("赵六", 19, 2999.9, Employee.Status.FREE),
        new Employee("田七", 18, 4999.9, Employee.Status.BUSY),
        new Employee("田七", 18, 4999.9, Employee.Status.BUSY),
        new Employee("田七", 18, 4999.9, Employee.Status.BUSY)
);

筛选得到salary>=5000的所有员工:

@Test
public void t3() {
    employees.stream()
            .filter(employee -> {
                System.out.println("短路!");
                return employee.getSalary()>=5000;
            })
            .limit(2)
            .forEach(System.out::println);
}

skip(n)跳过元素:

@Test
public void t4() {
    // 跳过前两个
    employees.stream()
            .filter(employee -> employee.getSalary()>=5000)
            .skip(2)
            .forEach(System.out::println);
}

distinct去重:

@Test
    public void t5() {
        // 去重
        employees.stream()
                .filter(employee -> employee.getSalary()>=5000)
                .distinct()
                .forEach(System.out::println);
    }

映射

  • map:接收Lambda,将元素转换成其他形式或提取信息接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素,然后返回保存所有新元素的新流

  • flatMap:接收一个函数作为参数, 将流中的每个值都换成另一个流,然后把所有流连接成一个流

@Test
publicvoid t1() {
    List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");
    // 转大写
    list.stream()
            .map(String::toUpperCase)
            .forEach(System.out::println);
    System.out.println("====================");

    // 获取所有员工姓名
    employees.stream()
            .map(Employee::getName)
            .forEach(System.out::println);
    System.out.println("====================");

    Stream<Stream<Character>> stream = list.stream()
    		.map(TestStreamAPI3::filterCharacter);
    // {{a,a,a},{b,b,b},{c,c,c},{d,d,d},{e,e,e}}
    stream.forEach(sm->{
        sm.forEach(System.out::println);
    });

    Stream<Character> characterStream = list.stream()
    		.flatMap(TestStreamAPI3::filterCharacter);
    characterStream.forEach(System.out::println);
}

public static Stream<Character> filterCharacter(String str) {
    List<Character> list = new ArrayList<>();
    for (char c : str.toCharArray()) {
        list.add(c);
    }
    return list.stream();
}

排序

  • sorted():自然排序(Comparable,对象的类已经实现的接口)
  • sorted(Comparator com):定制排序(Comparator,传入的自定义排序方式)
@Test
public void t2() {
    List<String> list = Arrays.asList("ccc","ddd","eee","bbb","aaa");
    list.stream()
            .sorted()
            .forEach(System.out::println);

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

    employees.stream()
            .sorted((o1, o2) -> {
                if (o1.getAge() != o2.getAge()) {
                    return Integer.compare(o1.getAge(), o2.getAge());
                }
                else {
                    return Double.compare(o1.getSalary(), o2.getSalary());
                }
            })
            .forEach(System.out::println);
}

3.终止操作

查找与匹配

  • allMatch:检查是否匹配所有元素
  • anyMatch:检查是否至少匹配一个元素
  • noneMatch:检查是否所有元素都不匹配
  • findFirst:返回第- - 个元素
  • findAny:返回当前流中的任意元素
  • count:返回流中元素的总个数
  • max:返回流中最大值
  • min:返回流中最小值
@Test
public void t1() {
    boolean b1 = employees.stream()
            .allMatch(employee -> employee.getStatus().equals(Employee.Status.BUSY));
    System.out.println(b1);

    boolean b2 = employees.stream()
            .anyMatch(employee -> employee.getStatus().equals(Employee.Status.BUSY));
    System.out.println(b2);

    boolean b3 = employees.stream()
            .noneMatch(employee -> employee.getStatus().equals(Employee.Status.BUSY));
    System.out.println(b3);

    Optional<Employee> op = employees.stream()
            .sorted((o1, o2) -> Double.compare(o1.getSalary(), o2.getSalary()))
            .findFirst();
    System.out.println(op.get());


    Optional<Employee> any = employees.stream()
            .filter(employee -> employee.getStatus().equals(Employee.Status.FREE))
            .findAny();
    System.out.println(any.get());
}
@Test
public void t2() {
    long count = employees.stream()
            .count();
    System.out.println(count);

    // 获取最高工资的员工
    Optional<Employee> max = employees.stream()
            .max((o1, o2) -> Double.compare(o1.getSalary(), o2.getSalary()));
    System.out.println(max.get());

    // 获取最低工资
    Optional<Double> min = employees.stream()
            .map(Employee::getSalary)
            .min(Double::compare);
    System.out.println(min.get());
}

归约

reduce(T identity, BinaryOperator) / reduce(BinaryOperator):可以将流中元素反复结合起来,得到一个值。

@Test
public void t3() {
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
    Integer sum = list.stream()
            .reduce(0, Integer::sum); // (x, y) -> x + y
    System.out.println(sum);

    Integer all = list.stream()
            .reduce(1, (x, y) -> x * y);
    System.out.println(all);

    // 获取工资总和
    Double salarySum = employees.stream()
            .map(Employee::getSalary)
            .reduce(0.0, Double::sum);
    System.out.println(salarySum);
}

收集

collect:将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法

@Test
public void t4() {
    List<String> names = employees.stream()
            .map(Employee::getName)
            .collect(Collectors.toList());
    names.forEach(System.out::println);
    System.out.println("=======================");

    Set<Employee.Status> collect = employees.stream()
            .map(Employee::getStatus)
            .collect(Collectors.toSet());
    collect.forEach(System.out::println);
    System.out.println("=======================");

    // 收集到特殊的集合中
    HashSet<String> set = employees.stream()
            .map(Employee::getName)
            .collect(Collectors.toCollection(HashSet::new));
    set.forEach(System.out::println);
}

统计最大(小)、平均值

@Test
public void t5() {
    Double avgSalary = employees.stream()
            .collect(Collectors.averagingDouble(Employee::getSalary));
    System.out.println(avgSalary);
    System.out.println("=======================");

    Double sumSalary = employees.stream()
            .collect(Collectors.summingDouble(Employee::getSalary));
    System.out.println(sumSalary);
    System.out.println("=======================");

    Optional<Employee> maxSalaryEmployee = employees.stream()
            .collect(Collectors.maxBy((o1, o2) -> Double.compare(o1.getSalary(), o2.getSalary())));
    System.out.println(maxSalaryEmployee.get());
    System.out.println("=======================");

    Optional<Double> minSalary = employees.stream()
            .map(Employee::getSalary)
            .collect(Collectors.minBy(Double::compare));
    System.out.println(minSalary.get());
}
@Test
public void t9() {
    DoubleSummaryStatistics dss = employees.stream()
            .collect(Collectors.summarizingDouble(Employee::getSalary));
    System.out.println(dss.getSum());
    System.out.println(dss.getMax());
    System.out.println(dss.getAverage());
}

分组

@Test
public void t6() {
    // 按照状态分组
    Map<Employee.Status, List<Employee>> group = employees.stream()
            .collect(Collectors.groupingBy(Employee::getStatus));
    group.forEach((status, employees) -> {
        System.out.println(status+": ");
        employees.forEach(System.out::println);
    });
}

多级分组

@Test
public void t7() {
    Map<Employee.Status, Map<String, List<Employee>>> collect = employees.stream()
            .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(employee -> {
                if (employee.getAge() <= 35) {
                    return "青年";
                }
                else if (employee.getAge() <= 50) {
                    return "中年";
                }
                else {
                    return "老年";
                }
            })));

    collect.forEach((status, ageMap) -> {
        System.out.println(status+": ");
        ageMap.forEach((ageTag, employeeList)->{
            System.out.println("\t"+ageTag+":");
            employeeList.forEach(employee -> System.out.println("\t\t"+employee));
        });
    });
}

分区

@Test
public void t8() {
    // 分区
    Map<Boolean, List<Employee>> map = employees.stream()
            .collect(Collectors.partitioningBy(employee -> employee.getSalary() >= 5000));
    map.forEach((key, employees)-> {
        System.out.println(key+": ");
        employees.forEach(employee -> System.out.println("\t"+employee));
    });
}

字符串连接

@Test
public void t10() {
    String str = employees.stream()
            .map(Employee::getName)
            .collect(Collectors.joining(",","[","]"));
    System.out.println(str);
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:36:16  更:2021-07-28 07:38:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 14:15:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码