为什么需要 Stream
Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 对 XML 解析的 Stream,也不是 Amazon Kinesis 对大数据实时处理的 Stream。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以说,Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物。
简单介绍Stream(流)
串行stream() − 为集合创建串行流。
串行 一个线程做完所有事情
优点:不存在什么线程安全问题,保证处理的先后顺序。
缺点:速度比较慢。
并行parallelStream() − 为集合创建并行流
并行 多个线程一起做
优点:处理速度快
缺点:线程安全处理不得当会引发灾难。
Stream(流)的使用
package com.example.demo.controller;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
List<String> list = Arrays.asList("att","btt","ctt","dtt","ett","ftt");
List<Integer> numbers = Arrays.asList(3,1,4,5,2,6);
Map<String,Object> map = new HashMap<>();
map.put("1","小黑");
map.put("2","小是");
map.put("3","小个");
map.put("4","小额");
map.put("5","小给");
//foreach遍历,用起来很方便
list.stream().forEach(s -> {
System.out.println(s+"520");
});
//filter通过设置的条件过滤出元素
List<String> collect = list.stream().filter(s -> s.contains("a")).collect(Collectors.toList());
System.out.println(collect.toString());
//map映射每一个结果
List<Integer> collect1 = numbers.stream().map(s -> s * 5).collect(Collectors.toList());
System.out.println(collect1.toString());
numbers.stream().map(s -> s*10).filter(s -> s>20).forEach(num ->{
System.out.println(num);
});
//limit显示多少数据
list.stream().limit(3).filter(s -> s.contains("a")).forEach(num ->{
System.out.println(num);
});
//sorted排序
List<Integer> collect2 = numbers.stream().sorted().collect(Collectors.toList());
System.out.println(collect2.toString());
//在map集合中能直接遍历对应的key和value,然后在进行操作
map.forEach((key,value) ->{
System.out.println(key+value);
});
map.entrySet().forEach(entry ->{
System.out.println(entry.getKey()+entry.getValue());
});
}
}
应用场景
我们经常会有返回树形结构数据的需求。比如商品信息,第一层是家用电器,家用电器又包含电视、空调等,电视又包括多款不同型号。这时我们要返回一个集合,包含多个层级关系。使用Stream API可以很方便的解决这个问题。
注意:这里我们的商品上下级之间以parentCid来关联,parentCid是指上一级商品的catId,顶级商品的parentCid为0。(如下图)
定义获取树形结构的方法
//获取树形结构
@Override
public List<CategoryEntity> listWithTree() {
List<CategoryEntity> entities = baseMapper.selectList(null);
List<CategoryEntity> list = entities.stream()
//过滤parentCid为0
.filter(categoryEntity -> categoryEntity.getParentCid() == 0)
.map(categoryEntity -> {
//递归添加子节点
categoryEntity.setChildren(getChildrens(categoryEntity,entities));
return categoryEntity;
})
//根据sort字段排序
.sorted((menue1,menue2) ->{
return (menue1.getSort() == null?0:menue1.getSort()) - (menue2.getSort() == null ?0:menue2.getSort());
})
.collect(Collectors.toList());
return list;
}
//递归遍历添加子节点数据
public List<CategoryEntity> getChildrens(CategoryEntity root,List<CategoryEntity> all){
List<CategoryEntity> entityList = all.stream()
.filter(categoryEntity -> categoryEntity.getParentCid() == root.getCatId())
.map(categoryEntity -> {
categoryEntity.setChildren(getChildrens(categoryEntity,all));
return categoryEntity;
})
.sorted((menue1,menue2) ->{
return (menue1.getSort() == null?0:menue1.getSort()) - (menue2.getSort() == null ?0:menue2.getSort());
})
.collect(Collectors.toList());
return entityList;
}
文章转载自stormMoonlet,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。