本文已经收录到 Github 仓库,该仓库包含计算机基础、Java 基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎 star~
Github地址
如果访问不了 Github,可以访问 gitee 地址。
gitee地址
Java8 新增的 Stream 流大大减轻了我们代码的工作量,但是 Stream 流的用法较多,实际使用的时候容易遗忘,整理一下供大家参考。
1. 概述
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来对 Java 集合运算和表达的高阶抽象。
Stream API 可以极大提高 Java 程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
2. 创建
2.1 集合自带 Stream 流方法
List<String> list = new ArrayList<>();// 创建一个顺序流Stream<String> stream = list.stream();// 创建一个并行流Stream<String> parallelStream = list.parallelStream();
复制代码
2.1 通过 Array 数组创建
最全面的Java面试网站
int[] array = {1,2,3,4,5};IntStream stream = Arrays.stream(array);
复制代码
2.3 使用 Stream 的静态方法创建
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);Stream<Integer> stream = Stream.iterate(0, (x) -> x + 3).limit(3); // 输出 0,3,6
Stream<String> stream = Stream.generate(() -> "Hello").limit(3); // 输出 Hello,Hello,HelloStream<Double> stream = Stream.generate(Math::random).limit(3); // 输出3个随机数
复制代码
2.3 数值流
// 生成有限的常量流IntStream intStream = IntStream.range(1, 3); // 输出 1,2IntStream intStream = IntStream.rangeClosed(1, 3); // 输出 1,2,3// 生成一个等差数列IntStream.iterate(1, i -> i + 3).limit(5).forEach(System.out::println); // 输出 1,4,7,10,13// 生成无限常量数据流IntStream generate = IntStream.generate(() -> 10).limit(3); // 输出 10,10,10
复制代码
另外还有 LongStream、DoubleStream 都有这几个方法。
3. 使用
初始化一些数据,示例中使用。
public class Demo { class User{ // 姓名 private String name;
// 年龄 private Integer age; }
public static void main(String[] args) { List<User> users = new ArrayList<>(); users.add(new User("Tom", 1)); users.add(new User("Jerry", 2)); }}
复制代码
3.1 遍历 forEach
// 循环输出user对象users.stream().forEach(user -> System.out.println(user));
复制代码
3.2 查找 find
// 取出第一个对象User user = users.stream().findFirst().orElse(null); // 输出 {"age":1,"name":"Tom"}// 随机取出任意一个对象User user = users.stream().findAny().orElse(null);
复制代码
3.3 匹配 match
// 判断是否存在name是Tom的用户boolean existTom = users.stream().anyMatch(user -> "Tom".equals(user.getName()));// 判断所有用户的年龄是否都小于5boolean checkAge = users.stream().allMatch(user -> user.getAge() < 5);
复制代码
3.4 筛选 filter
// 筛选name是Tom的用户users.stream() .filter(user -> "Tom".equals(user.name)) .forEach(System.out::println); // 输出 {"age":1,"name":"Tom"}
复制代码
3.5 映射 map/flatMap
// 打印users里的nameusers.stream().map(User::getName).forEach(System.out::println); // 输出 Tom Jerry// List<List<User>> 转 List<User>List<List<User>> userList = new ArrayList<>();List<User> users = userList.stream().flatMap(Collection::stream).collect(Collectors.toList());
复制代码
3.6 归约 reduce
// 求用户年龄之和Integer sum = users.stream().map(User::getAge).reduce(Integer::sum).orElse(0);// 求用户年龄的乘积Integer product = users.stream().map(User::getAge).reduce((x, y) -> x * y).orElse(0);
复制代码
3.7 排序 sorted
// 按年龄倒序排List<User> collect = users.stream() .sorted(Comparator.comparing(User::getAge).reversed()) .collect(Collectors.toList());
//多属性排序List<Person> result = persons.stream() .sorted(Comparator.comparing((Person p) -> p.getNamePinyin()) .thenComparing(Person::getAge)).collect(Collectors.toList());
复制代码
3.8 收集 collect
// list转换成mapMap<Integer, User> map = users.stream() .collect(Collectors.toMap(User::getAge, Function.identity()));
// 按年龄分组Map<Integer, List<User>> userMap = users.stream().collect(Collectors.groupingBy(User::getAge));
// 求平均年龄Double ageAvg = users.stream().collect(Collectors.averagingInt(User::getAge)); // 输出 1.5
// 求年龄之和Integer ageSum = users.stream().collect(Collectors.summingInt(User::getAge));
// 求年龄最大的用户User user = users.stream().collect(Collectors.maxBy(Comparator.comparing(User::getAge))).orElse(null);
// 把用户姓名拼接成逗号分隔的字符串输出String names = users.stream().map(User::getName).collect(Collectors.joining(",")); // 输出 Tom,Jerry
复制代码
3.9 List 转换成 Map 时遇到重复主键
这样转换会报错,因为 ID 重复。
可以这样做
好东西应该要分享出来!我把自己学习计算机多年以来的书籍分享出来了,汇总到一个计算机经典编程书籍仓库了,一共 300 多本,包括 C 语言、C++、Java、Python、前端、数据库、操作系统、计算机网络、数据结构和算法、机器学习、编程人生等,可以 star 一下,下次找书直接在上面搜索,仓库持续更新中~
Github地址
评论