Java Stream 常用操作有哪些
你平时买奶茶时,是不是会先把店里的所有奶茶列出来,再挑出热饮、按价格排序、最后只取前三名?其实代码里的“Stream流”,就像给程序开了个“奶茶挑选流水线”——不用一个个手动找,按步骤操作就能快速拿到想要的结果。今天就用奶茶店的例子,给大家讲讲Java Stream里最常用的几个操作,都是平时写代码时用得最多的。
第一步:先把杂乱的东西“整理成流水线”——创建Stream
就像你得先把奶茶店的所有奶茶(比如列表、数组)摆出来,才能开始挑选,Stream第一步得先创建。

举个例子:你手机里存了10杯奶茶的名字,存在一个列表里,要把它们转成Stream,代码就一行:
`List<String> milkTeas = Arrays.asList("珍珠奶茶", "芋泥啵啵", "柠檬茶", "抹茶拿铁");
Stream<String> teaStream = milkTeas.stream();`
就这么简单,把集合转成Stream,后面就能一步步操作了。
第二步:挑出符合要求的——过滤操作filter
这是Stream最常用的操作,对应你“挑热饮、挑加珍珠的奶茶”。
还是用奶茶例子,刚才的列表里有4款,你想挑出带“珍珠”的:
`List<String> pearlTeas = milkTeas.stream()
.filter(tea -> tea.contains("珍珠"))
.collect(Collectors.toList());`
运行后,结果就是["珍珠奶茶"]。
就像你在一堆奶茶里,只捡出带“珍珠”的,不符合的直接跳过,特别适合筛选数据。
第三步:把东西“换个样子”——映射操作map
有时候你需要把奶茶名字改成大写,或者提取价格,这时候就用map。
比如你想把所有奶茶名字转成大写,方便统一格式:
`List<String> upperTeas = milkTeas.stream()
.map(tea -> tea.toUpperCase())
.collect(Collectors.toList());`
结果就是["珍珠奶茶"→"珍珠奶茶全大写", "芋泥啵啵"→"芋泥啵啵全大写"]。
再复杂点,如果你有对象(比如每杯奶茶带价格的MilkTea类),想提取所有价格:
`List<Double> prices = milkTeaList.stream()
.map(MilkTea::getPrice)
.collect(Collectors.toList());`
MilkTea::getPrice就是“拿每杯奶茶的价格”,相当于把奶茶“拆出”价格属性,适合需要处理单个属性的情况。
第四步:把所有东西凑成一个——聚合操作reduce
假设你买了5杯奶茶,要算总花了多少钱,就需要reduce。它的作用是把Stream里的所有元素,按规则凑成一个结果。
比如算所有奶茶总价:
`double total = milkTeaList.stream()
.map(MilkTea::getPrice)
.reduce(0.0, (sum, price) -> sum + price);`
解释下:第一个参数0.0是初始值(没奶茶的话总价就是0),后面的(sum, price) -> sum + price是规则——把之前加的总和sum,加上当前奶茶的价格price,最后得到总钱数。
如果不用reduce,你得写个循环累加,Stream一行就能搞定,代码更简洁。
第五步:排序——排序操作sorted
买奶茶时你可能想按价格从低到高排,或者按名字首字母排,这就是sorted的作用。
比如把奶茶按价格从低到高排:
`List<MilkTea> sortedTeas = milkTeaList.stream()
.sorted(Comparator.comparingDouble(MilkTea::getPrice))
.collect(Collectors.toList());`
如果要倒序,加个reversed()就行:
.sorted(Comparator.comparingDouble(MilkTea::getPrice).reversed())
就像你把奶茶从最便宜到最贵摆好,一目了然。
这些操作都是“中间操作”,就像奶茶流水线里的“筛选、改样子、排序”,只会先记录步骤,不会立刻执行;最后一步的collect或者reduce是“终止操作”,会触发整个流程,得到最终结果。平时写代码时,这几个操作搭配用,能把复杂的数据处理变得像挑奶茶一样简单,不用再写一堆循环判断,代码既干净又好懂。