【Java8新特性】Stream API
2021/10/3 22:12:52
本文主要是介绍【Java8新特性】Stream API,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 1 Stream的实例化
- 1.1 通过集合创建
- 1.2 通过数组创建
- 1.3 通过Stream的of()
- 1.4 创建无限流
- 2 Stream的中间操作
- 2.1 筛选与切片
- 2.2 映射
- 2.3 排序
- 3 Stream的终止操作
- 3.1 匹配与查找
- 3.2 归约
- 3.3 收集
- 参考资料
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 归约
map
和reduce
的连接通常称为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 实用类
提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
参考资料
- 尚硅谷Java零基础入门教程(含百道Java真题,2万多行Java代码实战)
- 代码仓库
这篇关于【Java8新特性】Stream API的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-29RocketMQ底层原理资料详解:新手入门教程
- 2024-11-29RocketMQ源码资料解析与入门教程
- 2024-11-29[开源]6.1K star!这款电视直播源神器真的太赞啦!
- 2024-11-29HTTP压缩入门教程:轻松提升网页加载速度
- 2024-11-29JWT开发入门指南
- 2024-11-28知识管理革命:文档软件的新玩法了解一下!
- 2024-11-28低代码应用课程:新手入门全攻略
- 2024-11-28哪些办公软件适合团队协作,且能够清晰记录每个阶段的工作进展?
- 2024-11-28全栈低代码开发课程:零基础入门到初级实战
- 2024-11-28拖动排序课程:轻松掌握课程拖动排序功能