Java Stream API 的使用

server/2025/3/18 21:13:19/

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/server/176053.html

相关文章

深度学习技巧

胡适的英语老师、出版家王云五先生是这样自学英语写作的&#xff1a;找一篇英文的名家佳作&#xff0c;熟读几次以后&#xff0c;把它翻译成中文&#xff1b;一星期之后&#xff0c;再将中文反过来翻译成英文&#xff0c;翻译期间绝不查阅英语原文&#xff1b;翻译好后再与原文…

CF 230B. T-primes

题目 time limit per test&#xff1a;2 seconds&#xff1b;memory limit per test&#xff1a;256 megabytes We know that prime numbers are positive integers that have exactly two distinct positive divisors. Similarly, well call a positive integer t Т-prime,…

时间有限,如何精确设计测试用例?5种关键方法

精确设计测试用例能够迅速识别并修复主要缺陷&#xff0c;确保产品质量&#xff0c;降低后期维护成本&#xff0c;并通过专注于核心功能来提升用户体验&#xff0c;为项目的成功奠定坚实基础。若未能精确设计测试用例&#xff0c;可能会导致关键功能测试不充分&#xff0c;使得…

Pandas与PySpark混合计算实战:突破单机极限的智能数据处理方案

引言&#xff1a;大数据时代的混合计算革命 当数据规模突破十亿级时&#xff0c;传统单机Pandas面临内存溢出、计算缓慢等瓶颈。PySpark虽能处理PB级数据&#xff0c;但在开发效率和局部计算灵活性上存在不足。本文将揭示如何构建PandasPySpark混合计算管道&#xff0c;在保留…

定义模型生成数据表

1. 数据库配置 js import { Sequelize, DataTypes } from sequelize; // 创建一个 Sequelize 实例&#xff0c;连接到 SQLite 数据库。 export const sequelize new Sequelize(test, sa, "123456", { host: localhost, dialect: sqlite, storage: ./blog.db })…

第十五届蓝桥杯C/C++B组拔河问题详解

解题思路 这道题目的难点在于枚举所有区间&#xff0c;并且区间不能重合&#xff0c;那么这样感觉就很难了。但是用下面这种方法就会好很多。 我们只需要将左边的所有区间的各种和放在一个set中&#xff0c;然后我们在枚举右边的所有区间的和去和它进行比较&#xff0c;然后…

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_13可展开行的固定表头表格

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_13可展开行的固…

Java---网络初识

本文章用于理解网络中的各个关键字 1.IP地址 &#xff1a; 用于标识网络主机&#xff0c;和其他网络设备的网络地址 比如我们发快递时&#xff0c;需要知道对方的地址才能将包裹发送给他 格式&#xff1a; IPv4&#xff1a; IP地址是32位二进制数&#xff0c;如&#xff1…