Java Stream API 的使用

ops/2025/3/18 20:39:59/

java8引入的java.util.stream.Stream流操作,使得访问和操作数组(Array)、集合(Collection)变得非常方便和优雅。
1、过滤元素和转化元素类型

java">    private static void filterMapToInt() {List<String> list = new ArrayList<>();list.add("12");list.add("ab");list.add("34");int[] array = list.stream().filter(str -> {Pattern pattern = Pattern.compile("\\d+");return pattern.matcher(str).find();}).mapToInt(Integer::parseInt).toArray();System.out.println(Arrays.toString(array)); // [12, 34]}

2、平铺流元素和转化

java">    private static void flatMapStreamOfMap() {List<String> list = new ArrayList<>();list.add("12,ab,34");list.add("11,22,bb");Stream<String> stream = list.stream();Stream<String> stringStream = stream.flatMap(str -> Stream.of(str.split(",")).map(String::toUpperCase));System.out.println(stringStream.toList()); // [12, AB, 34, 11, 22, BB]}

3、嵌套类型转为列表

java">private static void mapMulti() {List<Object> objects = List.of(1, List.of(2, List.of(3, 4)), 5);Stream<Object> objectStream = objects.stream().mapMulti(StreamTest::expandIterable);List<Integer> list = objectStream.map(o -> Integer.parseInt(o.toString())).toList();System.out.println(list); // [1, 2, 3, 4, 5]}static void expandIterable(Object e, Consumer<Object> c) {if (e instanceof Iterable<?> elements) {for (Object ie : elements) {expandIterable(ie, c);}} else if (e != null) {c.accept(e);}}

4、多个数据类型转为单一类型

java">private static void mapMulti2() {Map<String, Object> map = new HashMap<>();map.put("aa", new Object());map.put("23.3", new Object());List<Object> objects = List.of(1, map, 1.345f, List.of("bb", 2.45d));// 整数不变,浮点数转化为整数,字符串丢弃,map只需要keyStream<Object> objectStream = objects.stream().mapMulti(StreamTest::handleMapMulti);System.out.println(objectStream.map(object -> Integer.parseInt(object.toString())).toList()); // [1, 23, 1, 2]}static void handleMapMulti(Object e, Consumer<Object> c) {if (e instanceof Iterable<?> elements) {for (Object ie : elements) {handleMapMulti(ie, c);}} else if (e != null) {Object intTarget = e;if (e instanceof Map<?, ?> map) {handleMapMulti(map.keySet(), c);}if (intTarget instanceof Float f) {intTarget = Math.round(f);}if (intTarget instanceof Double d) {intTarget = (int) Math.round(d);}if (intTarget instanceof String str) {try {intTarget = (int) Float.parseFloat(str);} catch (NumberFormatException _) {}}if (intTarget instanceof Integer integer) {c.accept(integer);}}}

5、元素去重

java">    private static void distinct() {List<String> list = new ArrayList<>();list.add("aa");list.add("aa");list.add("bb");System.out.println(list.stream().distinct().toList()); // [aa, bb]}

6、无参数排序(元素自己实现了Comparable)

java">    private static void sortedByItself() {List<Integer> list = new ArrayList<>();list.add(1);list.add(3);list.add(2);System.out.println(list.stream().sorted().toList()); // [1, 2, 3]System.out.println(list.stream().sorted(Comparator.reverseOrder()).toList()); // [3, 2, 1] 倒序}

7、有参数排序(传入Comparator)

java">    private static void sortedByComparator() {List<String> list = new ArrayList<>();list.add("xiaoming,96");list.add("xiaohong,80");list.add("xiaozhang,100");List<String> list1 = list.stream().sorted((s1, s2) -> {String[] info1 = s1.split(",");String[] info2 = s2.split(",");int score1 = Integer.parseInt(info1[1]);int score2 = Integer.parseInt(info2[1]);return score2 - score1;}).toList();System.out.println(list1); // [xiaozhang,100, xiaoming,96, xiaohong,80]}

8、用于debug程序的peek

java">    private static void debugByPeek() {List<String> list = Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3).peek(e -> System.out.println("Filtered value: " + e)).map(String::toUpperCase).peek(e -> System.out.println("Mapped value: " + e)).toList();System.out.println(list);}

打印:
Filtered value: three
Mapped value: THREE
Filtered value: four
Mapped value: FOUR
[THREE, FOUR]

9、限制返回个数

java">    private static void limit() {List<Integer> list = new ArrayList<>();list.add(1);list.add(3);list.add(2);System.out.println(list.stream().limit(2).toList()); // [1, 3]}

10、跳过若干个元素

java">    private static void skip() {List<Integer> list = new ArrayList<>();list.add(1);list.add(3);list.add(2);System.out.println(list.stream().skip(2).toList()); // [2]}

11、有条件的获取元素(java9)

java">    private static void taskWhile() {Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);// 使用 takeWhile 提取元素,直到遇到第一个大于 5 的元素Stream<Integer> takenStream = stream.takeWhile(n -> n <= 5);// 输出提取的元素takenStream.forEach(System.out::print); // 12345}

12、有条件的丢弃元素(java9)

java">    private static void dropWhile() {Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);// 使用 dropWhile 提取元素,丢弃小于等于 5 的元素Stream<Integer> takenStream = stream.dropWhile(n -> n <= 5);// 输出提取的元素takenStream.forEach(System.out::print); // 678910}

13、按顺序执行(并行流(多线程)也能按顺序)

java">    private static void foreachOrdered() {// 在并行流中,forEachOrdered 需要额外的同步机制来保证顺序,因此性能可能不如 forEach。如果顺序不重要,优先使用 forEach// 如果流本身是无序的(例如 HashSet 的流),forEachOrdered 的行为可能与 forEach 相同// 在串行流中,forEach 和 forEachOrdered 的行为几乎一致Stream<Integer> parallelStream = Stream.of(1, 2, 3, 4, 5).parallel();parallelStream.forEach(System.out::print); // 34152 顺序不保证Stream<Integer> parallelStream2 = Stream.of(1, 2, 3, 4, 5).parallel();parallelStream2.forEachOrdered(System.out::print); // 12345 顺序保证}

14、转为list或者转为数组

java">    private static void toListToArray() {String s = "1,2,3";List<String> list = Stream.of(s.split(",")).toList();Object[] objectArr = Stream.of(s.split(",")).toArray();String[] strArr = Stream.of(s.split(",")).toArray(String[]::new);Integer[] intArr = Stream.of(s.split(",")).map(Integer::parseInt).toArray(Integer[]::new);System.out.println("stream.toList:" + list);System.out.println("stream.toArray:" + Arrays.toString(objectArr));System.out.println("stream.toArray(String[]::new):" + Arrays.toString(strArr));System.out.println("stream.toArray(Integer[]::new):" + Arrays.toString(intArr));}

打印:
stream.toList:[1, 2, 3]
stream.toArray:[1, 2, 3]
stream.toArray(String[]::new):[1, 2, 3]
stream.toArray(Integer[]::new):[1, 2, 3]

15、将列表转个单个元素(累积函数,根据某个规则将多个元素合并)

java">    private static void reduce() {List<Integer> numbers = Arrays.asList(1, 2, 3);Optional<Integer> sum = numbers.stream().reduce(Integer::sum); // 求和System.out.println(sum.orElse(0)); // 输出 6Optional<Integer> max = numbers.stream().reduce(Integer::max);// 最大值System.out.println(max.orElse(0)); // 输出 3List<String> list = Arrays.asList("Hello ", "world!");String concat = list.stream().reduce("", String::concat); // 字符调拼接System.out.println(concat); // Hello world!// 初始值(identity)// 必须是累积函数的单位元,即满足:// accumulator.apply(identity, t) == t// 例如:加法初始值为0(0 + t = t),乘法初始值为1(1 * t = t)List<Integer> intList = Arrays.asList(1, 2, 3);int product = intList.stream().reduce(1, (a, b) -> a * b);System.out.println(product); // 输出 6}

16、把流转化为集合、Set或者对流分组和分区

java">  private static void collect() {// 转为 List (等价于:Stream.of("1", "2", "3").toList())List<String> list = Stream.of("1", "2", "3").collect(Collectors.toList());// 转为 Set(自动去重)Set<String> set = Stream.of("1", "2", "3").collect(Collectors.toSet());// 转为特定集合类型TreeSet<String> treeSet = Stream.of("1", "2", "3").collect(Collectors.toCollection(TreeSet::new));// 直接拼接 (等价于: String.join("", "1", "2", "3");)String joined = Stream.of("1", "2", "3").collect(Collectors.joining());// 带分隔符(等价于:String.join(", ", "1", "2", "3");)String joinedWithComma = Stream.of("1", "2", "3").collect(Collectors.joining(", "));// 带前缀和后缀String wrapped = Stream.of("1", "2", "3").collect(Collectors.joining(", ", "[", "]"));// 平均值Double avg = Stream.of("1", "2", "3").collect(Collectors.averagingInt(Integer::parseInt));// 总和 (等价于:Stream.of("1", "2", "3").mapToInt(Integer::parseInt).sum();)Integer sum = Stream.of("1", "2", "3").collect(Collectors.summingInt(Integer::parseInt));// 基础用法(键重复会抛出异常)Map<String, Integer> map = Stream.of(new Student(93, "xiaoming")).collect(Collectors.toMap(Student::getName,  // 键提取函数Student::getScore // 值提取函数));// 处理键冲突(第三个参数定义合并策略)Map<String, Integer> safeMap = Stream.of(new Student(93, "xiaoming"), new Student(94, "xiaohong"), new Student(6, "xiaohong")).collect(Collectors.toMap(Student::getName,Student::getScore,Integer::sum // 合并重复键的值));// 自定义 Map 类型(如 LinkedHashMap)Map<String, Integer> linkedMap = Stream.of(new Student(93, "xiaoming"), new Student(94, "xiaoming")).collect(Collectors.toMap(Student::getName,Student::getScore,(oldVal, _) -> oldVal,LinkedHashMap::new));// 示例:自定义收集到逗号分隔的字符串Collector<Student, StringJoiner, String> customCollector =Collector.of(() -> new StringJoiner(","), // Supplier(初始化容器)(j, e) -> j.add(e.getName()), // Accumulator(累加器:添加元素)StringJoiner::merge,          // Combiner(多线程:合并并行结果)StringJoiner::toString        // Finisher(最终转换));String names = Stream.of(new Student(93, "xiaoming"), new Student(94, "xiaohong")).collect(customCollector);System.out.println(names); // xiaoming, xiaohong// 分区(按布尔条件分为两组)Map<Boolean, List<Student>> partition = Stream.of(new Student(93, "xiaoming"), new Student(94, "xiaohong")).collect(Collectors.partitioningBy(e -> e.getScore() > 93));System.out.println(partition);  // {false=[score=93, name='xiaoming], true=[score=94, name='xiaohong]}// 按学科分组(默认返回 Map<K, List<T>>)Map<String, List<Student>> groupByDept = Stream.of(new Student(93, "xiaoming", "English")).collect(Collectors.groupingBy(Student::getSubject));// 分组后统计(下游收集器,统计每个学科有多少人)Map<String, Long> countByDept = Stream.of(new Student(93, "xiaoming", "English")).collect(Collectors.groupingBy(Student::getSubject,Collectors.counting() // 统计每组的元素数量));}static class Student {int score;String name;String subject;}

代码中Student省略getter、setter和构造函数

17、求最大值最小值

java">    private static void minMax() {Optional<Integer> min = Stream.of(1, 2, 3).min(Integer::compareTo);System.out.println(min.orElse(0)); // 1Optional<Integer> max = Stream.of(1, 2, 3).max(Integer::compareTo);System.out.println(max.orElse(4)); // 3}

18、计算流包含的元素个数

java">    private static void count() {System.out.println(Stream.of(1,2,3).count()); // 3}

19、执行条件匹配的判断

java">    private static void anyMatchAllMatchNoneMatch() {System.out.println(Stream.of(1, 2, 3).anyMatch(num -> num > 1));  // trueSystem.out.println(Stream.of(1, 2, 3).allMatch(num -> num > 2));  // false,不是全都大于2System.out.println(Stream.of(1, 2, 3).noneMatch(num -> num > 1)); // false,存在匹配的数据}

20、查找流的第一个元素或者任意一个元素

java">    private static void findFirstFindAny() {Optional<Integer> first = Stream.of(null, 2, 3).findFirst(); // java.lang.NullPointerExceptionOptional<Integer> one = Stream.of(1, 2, 3).findFirst(); // 1System.out.println(Stream.of(1, 2, 3).findAny().get()); // 其中一个,也会报空指针异常的可能}

21、通过构造器生成流

java">    private static void builder() {// add(T t)	添加元素到流,返回 Builder 自身(支持链式调用)// accept(T t)	与 add 功能相同,但返回 void(实现 Consumer 接口)// build()	构建最终的 Stream,之后不能再修改Stream.Builder<String> builder = Stream.builder();builder.add("Apple");builder.add("Banana").add("Cherry"); // 链式调用Stream<String> stream = builder.build();stream.forEach(System.out::println); // 输出:Apple Banana Cherry}

22、无限流的构造以及无限流的终止

java">    private static void iterate() {// static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)// iterate是一个用于生成无限流或有限流的静态方法, 生成一个无限流,从初始值seed开始,依次应用UnaryOperator生成后续元素// 在java8中结合limit来限制个数,java9中允许通过条件(predicate)来终止迭代// 生成偶数序列:0, 2, 4, 6, ...Stream<Integer> evenNumbers = Stream.iterate(0, n -> n + 2);// 通常需要结合 limit() 截断无限流(java8)evenNumbers.limit(5).forEach(System.out::println); // 输出 0 2 4 6 8// 生成数字直到小于 10:0, 1, 2, ..., 9 (java9)Stream<Integer> numbers = Stream.iterate(0,n -> n < 10, // 条件:当 n < 10 时继续n -> n + 1   // 迭代函数);numbers.forEach(System.out::println); // 输出 0 到 9}

http://www.ppmy.cn/ops/166860.html

相关文章

五子棋小游戏-简单开发版

一、需求分析 开发一个基于 Pygame 库的五子棋小游戏&#xff0c;允许两名玩家在棋盘上轮流落子&#xff0c;当有一方达成五子连珠时游戏结束&#xff0c;显示获胜信息&#xff0c;并提供退出游戏和重新开始游戏的操作选项。 1.棋盘显示 &#xff1a; 显示一个 15x15 的五子棋…

Redis--补充类型

目录 一、引言 二、补充类型 1.streams 2.geospatial 3.hyperloglog 4.bitmap 5.bitfields 三、总结 一、引言 在简单学习了redis中的5个数据类型&#xff08;string&#xff0c;list&#xff0c;hash&#xff0c;set&#xff0c;zset&#xff09;之后&#xff0c;本篇文…

视频AI方案:数据+算力+算法,人工智能的三大基石

背景分析 随着信息技术的迅猛发展&#xff0c;人工智能&#xff08;AI&#xff09;已经逐渐渗透到我们生活的各个领域&#xff0c;从智能家居到自动驾驶&#xff0c;从医疗诊断到金融风控&#xff0c;AI的应用正在改变着我们的生活方式。而数据、算法和算力&#xff0c;正是构…

R语言——变量

参考资料&#xff1a;学习R 1、类 R中所有变量都有一个类&#xff0c;表明此变量属于什么类型。例如&#xff0c;大部分的数字是numeric类&#xff0c;逻辑值是logical类。其实&#xff0c;因为R没有标量类型&#xff08;scalar type&#xff09;&#xff0c;所以更严格地我说…

peach模糊测试工具中,stateModel模块中的type的作用

嗯&#xff0c;用户问的是Peach模糊测试工具的Pit文件中的状态模型里&#xff0c;type"output"是什么意思。我需要结合用户提供的Pit文件内容和搜索结果来解答这个问题。 首先&#xff0c;用户提供的Pit文件中有一个StateModel&#xff0c;其中包含一个状态名为&quo…

Windows11 新机开荒(二)电脑优化设置

目录 前言&#xff1a; 一、注册微软账号绑定权益 二、此电脑 桌面图标 三、系统分盘及默认存储位置更改 3.1 系统分盘 3.2 默认存储位置更改 四、精简任务栏 总结&#xff1a; 前言&#xff1a; 本文承接上一篇 新机开荒&#xff08;一&#xff09; 上一篇文章地址&…

基于PHP的网店进销存管理系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 相比于以前的传统进销存管理方式&#xff0c;智能化的管理方式可以大幅降低进销存管理的运营人员成本&#xff0c;实现了进销存管理的标准化、制度化、程序化的管理&#xff0c;有效地防止了商品信息及仓库信息的随意管理&#xff0c;提高了信息的处理速度和精确度&#…

Python游戏开发自学指南:从入门到实践(第四天)

Python不仅适用于数据分析、Web开发和自动化脚本&#xff0c;还可以用于游戏开发&#xff01;虽然Python不是传统意义上的游戏开发语言&#xff0c;但其简洁的语法和丰富的库使其成为初学者学习游戏开发的绝佳选择。本文将为你提供一份全面的Python游戏开发自学指南&#xff0c…