ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【Java8新特性】Stream API

2021-10-03 21:00:14  阅读:196  来源: 互联网

标签:stream Stream employees System API println Java8 out


文章目录

1 Stream的实例化

1.1 通过集合创建

// 集合获取stream
@Test
public void test1() {
    List<Employee> employees = EmployeeData.getEmployees();
    // 返回一个顺序流
    Stream<Employee> stream = employees.stream();
    // 返回一个并行流
    Stream<Employee> parallelStream = employees.parallelStream();
}

1.2 通过数组创建

// 数组获取stream
@Test
public void test2() {
    // 基本类型
    int[] arr = new int[]{1, 2, 3, 4, 5};
    IntStream stream = Arrays.stream(arr);

    // 自定义类型
    Employee[] employees = new Employee[]{
            new Employee(),
            new Employee(),
    };
    Stream<Employee> employeeStream = Arrays.stream(employees);
}

1.3 通过Stream的of()

// 通过Stream的of()获取
    @Test
    public void test3() {
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
    }

1.4 创建无限流

// 创建无限流
@Test
public void test4() {
    // 迭代
    // 遍历前10个偶数
    Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);
    // 生成
    Stream.generate(Math::random).limit(10).forEach(System.out::println);
}

2 Stream的中间操作

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

2.1 筛选与切片

在这里插入图片描述

@Test
public void test1() {
    List<Employee> list = EmployeeData.getEmployees();
    // filter:查询薪资大于7000的员工信息
    list.stream().filter(employee -> employee.getSalary() > 7000).forEach(System.out::println);
    System.out.println("**************************");
    // 一旦执行终止操作,就得重新创建一个流
    // limit:截断流
    list.stream().limit(3).forEach(System.out::println);
    System.out.println("**************************");
    // skip:跳过元素
    list.stream().skip(3).forEach(System.out::println);
    System.out.println("**************************");
    // 跳过的元素数量,大于,流中的元素个数,返回一个空流
    list.stream().skip(30).forEach(System.out::println);
    System.out.println("**************************");
    // distinct:通过流中元素的hashcode()和equals()去除重复元素
    list.add(new Employee(1008, "扎克伯格", 35, 2500.32));
    list.add(new Employee(1008, "扎克伯格", 35, 2500.32));
    list.add(new Employee(1008, "扎克伯格", 35, 2500.32));
    System.out.println("原来的list有重复的值");
    list.stream().forEach(System.out::println);
    System.out.println("在流中去除重复的值");
    list.stream().distinct().forEach(System.out::println);
}

2.2 映射

在这里插入图片描述

//2-映射
@Test
public void test2() {
//        map(Function f)——接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数会被应用到每个元素上,并将其映射成一个新的元素。
    List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
    list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);

//        练习1:获取员工姓名长度大于3的员工的姓名。
    System.out.println("**************************");
    List<Employee> employees = EmployeeData.getEmployees();
    // 先从employees取出名字的流
//        Stream<String> nameStream = employees.stream().map(employee -> employee.getName());
    Stream<String> nameStream = employees.stream().map(Employee::getName);
    // 再从这个流中筛选出长度大于3的
    nameStream.filter(name -> name.length() > 3).forEach(System.out::println);
    System.out.println("**************************");
    // 练习2:
    Stream<Stream<Character>> streamStream = list.stream().map(StreamAPITest1::fromStringToStream);
    streamStream.forEach(s -> {
        s.forEach(System.out::println);
    });
    System.out.println("**************************");
    // 注意对比,map遍历了两遍,flatMap遍历了一遍
    Stream<Character> characterStream = list.stream().flatMap(StreamAPITest1::fromStringToStream);
    characterStream.forEach(System.out::println);
}

//将字符串中的多个字符构成的集合转换为对应的Stream的实例
public static Stream<Character> fromStringToStream(String str) {//aa
    ArrayList<Character> list = new ArrayList<>();
    for (Character c : str.toCharArray()) {
        list.add(c);
    }
    return list.stream();
}

2.3 排序

在这里插入图片描述

@Test
public void test3() {
//        sorted()——自然排序
    List<Integer> list = Arrays.asList(25, 45, 36, 12, 85, 64, 72, -95, 4);
    list.stream().sorted().forEach(System.out::println);
    // 抛异常,原因:Employee没有实现Comparable接口
    List<Employee> employees = EmployeeData.getEmployees();
//        employees.stream().sorted().forEach(System.out::println);
//        sorted(Comparator com)——定制排序
    employees.stream().sorted((e1, e2) -> {
        int ageValue = Integer.compare(e1.getAge(), e2.getAge());
        if (ageValue != 0) {
            return ageValue;
        } else {
            return Double.compare(e1.getSalary(), e2.getSalary());
        }
    }).forEach(System.out::println);
}

3 Stream的终止操作

3.1 匹配与查找

  • 终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是void。
  • 流进行了终止操作后,不能再次使用
    在这里插入图片描述
    在这里插入图片描述
@Test
public void test1() {
    List<Employee> employees = EmployeeData.getEmployees();

    // allMatch(Predicate p)——检查是否匹配所有元素。
    // 练习:是否所有的员工的年龄都大于18
    boolean allMatch = employees.stream().allMatch(employee -> employee.getAge() > 18);
    System.out.println(allMatch);

    // anyMatch(Predicate p)——检查是否至少匹配一个元素。
    // 练习:是否存在员工的工资大于 10000
    boolean anyMatch = employees.stream().anyMatch(employee -> employee.getSalary() > 10000);
    System.out.println(anyMatch);

    // noneMatch(Predicate p)——检查是否没有匹配的元素。
    //  练习:是否存在员工姓“马”
    boolean noneMatch = employees.stream().noneMatch(employee -> employee.getName().startsWith("雷"));
    System.out.println(noneMatch);

    // findFirst——返回第一个元素
    Optional<Employee> employee = employees.stream().findFirst();
    System.out.println(employee);

    // findAny——返回当前流中的任意元素
    // Optional<Employee> employee1 = employees.stream().findAny();
    Optional<Employee> employee1 = employees.parallelStream().findAny();
    System.out.println(employee1);

    // count——返回流中元素的总个数
    long count = employees.stream().filter(e -> e.getSalary() > 5000).count();
    System.out.println(count);

    // max(Comparator c)——返回流中最大值
    // 练习:返回最高的工资:
//        Stream<Double> salaryStream = employees.stream().map(e -> e.getSalary());
    Stream<Double> salaryStream = employees.stream().map(Employee::getSalary);
    Optional<Double> maxSalary = salaryStream.max(Double::compareTo);
    System.out.println(maxSalary);

    // min(Comparator c)——返回流中最小值
    // 练习:返回最低工资的员工
    Optional<Employee> min = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
    System.out.println(min);

    // forEach(Consumer c)——内部迭代
    employees.stream().forEach(System.out::println);
    System.out.println("********************************");
    employees.forEach(System.out::println);
}

3.2 归约

  • mapreduce的连接通常称为map-reduce模式,因Google用它来进行网络搜索而出名。
    在这里插入图片描述
@Test
public void test2() {
    // reduce(T identity, BinaryOperator)——可以将流中元素反复结合起来,得到一个值。返回 T
    // 练习1:计算1-10的自然数的和
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
//        Integer sum = list.stream().reduce(0, (o1, o2) -> o1 + o2);
    Integer sum = list.stream().reduce(0, Integer::sum);
    System.out.println(sum);

    // reduce(BinaryOperator) ——可以将流中元素反复结合起来,得到一个值。返回 Optional<T>
    // 练习2:计算公司所有员工工资的总和
    List<Employee> employees = EmployeeData.getEmployees();
    Optional<Double> sumSalary = employees.stream().map(Employee::getSalary).reduce(Double::sum);
    System.out.println(sumSalary);
}

3.3 收集

在这里插入图片描述

  • Collector 接口中方法的实现,决定了如何对流执行收集的操作(如收集到List、Set、Map)。
  • 另外,Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

在这里插入图片描述
在这里插入图片描述

参考资料

  1. 尚硅谷Java零基础入门教程(含百道Java真题,2万多行Java代码实战)
  2. 代码仓库

标签:stream,Stream,employees,System,API,println,Java8,out
来源: https://blog.csdn.net/Awt_FuDongLai/article/details/120594890

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有