流是什么
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素队列:特定类型的对象形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源:流的来源。可以是集合,数组,I/O channel, 产生器generator 等。
- 聚合操作:类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
- Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
- 内部迭代:以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
流的组成
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
流操作分类
- 中间操作(intermediate operation)
- 无状态操作
- 过滤(filter)
- 映射(map)
- 扁平化(flatMap)
- 遍历(peek)
- 有状态操作
- 去重(distinct)
- 跳过(slip)
- 截断(limit)
- 排序(sorted)
- 终端操作(terminal operation)
- 非短路操作
- 遍历(forEach)
- 归约(reduce)
- 最大值(max)
- 最小值(min)
- 聚合(collect)
- 计数(count等)
- 短路操作
- 所有匹配(allMatch)
- 任意匹配(anyMatch)
- 不匹配(noMatch)
- 查找首个(findFirst)
- 查找任意(findAny)
实例
public class StreamOperatorTest {
private static List<Goods> goodsList= new ArrayList<Goods>(){
{
add(new Goods(111,"无人机", GoodTypeEnum.DIGITAL,10000.00, 10000.00,1));
add(new Goods(112,"VR一体机", GoodTypeEnum.DIGITAL,13000.00, 13000.00,1));
add(new Goods(113,"衬衫", GoodTypeEnum.APPAREL,100.00, 300.00,3));
add(new Goods(114,"牛仔裤", GoodTypeEnum.APPAREL,120.00, 120.00,1));
add(new Goods(115,"Java编程思想", GoodTypeEnum.BOOKS,80.00, 80.00,1));
add(new Goods(116,"Java核心技术", GoodTypeEnum.BOOKS,90.00, 90.00,1));
add(new Goods(117,"算法", GoodTypeEnum.BOOKS,60.00, 60.00,1));
add(new Goods(118,"跑步机", GoodTypeEnum.SPORTS,3600.00, 3600.00,1));
}
};
@Test
public void forEachTest(){
goodsList.stream()
.forEach(goods->System.out.println(JSON.toJSONString(goods)));
}
@Test
public void filterTest(){
goodsList.stream()
.filter(goods-> GoodTypeEnum.BOOKS.equals(goods.getGoodType()))
.forEach(goods->System.out.println(JSON.toJSONString(goods)));
}
@Test
public void mapTest(){
goodsList.stream()
.map(goods-> goods.getGoodName())
.forEach(goods->System.out.println(JSON.toJSONString(goods,true)));
}
@Test
public void flatMapTest(){
goodsList.stream()
.flatMap(goods-> Arrays.stream(goods.getGoodName().split("")))
.forEach(goods->System.out.println(JSON.toJSONString(goods,true)));
}
@Test
public void peekTest(){
goodsList.stream()
.peek(goods-> System.out.println(goods.getGoodName()))
.forEach(goods->System.out.println(JSON.toJSONString(goods,true)));
}
@Test
public void sortedTest(){
goodsList.stream()
.sorted(Comparator.comparing(goods -> goods.getGoodPrice()))
.forEach(goods->System.out.println(JSON.toJSONString(goods)));
}
@Test
public void distinctTest(){
goodsList.stream()
.map(goods ->goods.getGoodType())
.distinct()
.forEach(goods->System.out.println(JSON.toJSONString(goods)));
}
@Test
public void skipTest(){
goodsList.stream()
.sorted(Comparator.comparing(goods -> goods.getGoodPrice()))
.skip(2)
.forEach(goods->System.out.println(JSON.toJSONString(goods)));
}
@Test
public void limitTest(){
goodsList.stream()
.sorted(Comparator.comparing(goods -> goods.getGoodPrice()))
.limit(2)
.forEach(goods->System.out.println(JSON.toJSONString(goods)));
}
@Test
public void allMatchTest(){
boolean allMatch =goodsList.stream()
.peek(goods->System.out.println(JSON.toJSONString(goods)))
.allMatch(goods -> goods.getGoodPrice()>500);
System.out.println(allMatch);
}
@Test
public void anyMatchTest(){
boolean allMatch =goodsList.stream()
.peek(goods->System.out.println(JSON.toJSONString(goods)))
.anyMatch(goods -> goods.getGoodPrice()>1000);
System.out.println(allMatch);
}
@Test
public void noneMatchTest(){
boolean allMatch =goodsList.stream()
.peek(goods->System.out.println(JSON.toJSONString(goods)))
.noneMatch(goods -> goods.getGoodPrice()>10000);
System.out.println(allMatch);
}
@Test
public void findFirstTest(){
Optional optional =goodsList.stream()
.findFirst();
System.out.println(JSON.toJSONString(optional.get()));
}
@Test
public void findAnyTest(){
for (int i = 0; i < 20; i++) {
Optional optional =goodsList.stream()
.findAny();
System.out.println(JSON.toJSONString(optional.get()));
}
}
@Test
public void mapToXXTest(){
DoubleSummaryStatistics stats = goodsList.stream()
.map(goods ->goods.getGoodPrice())
.mapToDouble((x)-> x).summaryStatistics();
System.out.println("商品中价格最贵的商品 : " + stats.getMax());
System.out.println("商品中价格最便宜的商品 : " + stats.getMin());
System.out.println("所有商品的价格之和 : " + stats.getSum());
System.out.println("商品的平均数 : " + stats.getAverage());
}
}
流的构建
- 由值创建流
- 由数组创建流
- 由文件创建流
- 由函数生产流
实例
收集器
- 将流中的元素累积成一个结果
- 作用于终端操作的collect()上
- collect/Collector/Collectors
预定义收集器功能
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!