Java 8 Steam API已经问世挺久了,以前也有所运用,觉得使用函数式编程,不能了解背后的原理,因而习惯性的写原生方法,例如写java原生的for来的顺手一些。最近接触了steam API的写法,逐渐重新认识了上它,以后也会在工作中多多用上stream API。
流(Stream)的概念:
流是数据渠道,用于操作数据(集合、数组等)所生成的元素序列。
Stream的操作三个步骤:
- 创建Stream:一个数据源(如数组、集合),获取一个流
- 中间操作:一个中间操作链,对数据源的数据进行处理
- 终止操作(终端操作):一个终止操作,执行中间操作链,并产生结果
中间操作:
- filter -------- 接受Lambda ,从流中排除某些元素
- limit --------- 截断流,使其元素不超过给定数量
- skip(n) ------- 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
- distinct ------ 筛选,通过流所生成元素的hashCode() 和 equals() 去除重复元素
映射:
- map ------ 接收Lambda,将元素转换为其他形式或提取信息(接受一个函数作为参数,该函数被应用到每个元素上,并将其映射成一个新的元素)
- flatMap ---- 接收一个函数作为参数,将流中的每个值都换成另外一个流,然后把所有的流连凑成一个流。
排序:
- sorted() ---- 自然排序
- sorted(Comparator comparator) ------ 定制排序(Comparator )
终止操作
查找与匹配:
- allMatch ----- 检查是否匹配所有元素
- anyMatch ------ 检查是否至少匹配一个元素
- noneMatch --------- 检查是否没有匹配所有元素
- findFirst ------- 返回第一个元素
- findAny -------- 返回流中的任意元素
- count ----------- 返回流中元素的总个数
- max ------- 返回流中的最大值
- min ------ 返回流中的最小值
归约:可以将流中元素反复结合起来,得到一个值
- reduce(T indentity,BinaryOperator bin) ---- indentity 为起始值
- reduce(BinaryOperator bin)
收集:
- collect ----- 将流装换为其它形式,接受一个Collector接口的实现,用于给Stream中元素汇总的方法
案例Demo:
#1 新建一个实体类: `
public class Apple {
private String name;
private Integer weight;
private String color;
private String remark;
public Apple(String name, Integer weight, String color,String remark) {
this.name = name;
this.weight = weight;
this.color = color;
this.remark=remark;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
#2 进行初始化List:
List<Apple> appleList = new ArrayList<>();
appleList.add(new Apple("广东",200,"红色","{"Normal":"0","Alarm":"1"}"));
appleList.add(new Apple("华南",200,"绿色","{"Normal":"1","Alarm":"1"}"));
appleList.add(new Apple("湖南",600,"黄色","{"Normal":"1","Alarm":"1"}"));
appleList.add(new Apple("广东",400,"红色","{"Normal":"0","Alarm":"1"}"));
appleList.add(new Apple("广东",50,"蓝色","{"Normal":"0","Alarm":"1"}"));
appleList.add(new Apple("湖南",80,"蓝色","{"Normal":"0","Alarm":"1"}"));
#3 过滤颜色是蓝色的Apple
List<Apple> res2 = appleList.stream().filter(a -> "蓝色".equals(a.getColor())).collect(Collectors.toList());
output:
蓝色-广东
蓝色-湖南
#4 新建一个映射类,AppleMappingEntity,将apple的remark字段的json进行转换,这种情况用stream API就比较方便 高效
public class AppleMappingEntity {
private ObjectMapper objMapper = new ObjectMapper();
private Apple apple;
private Map<String, String> valueMap;
public AppleMappingEntity(Apple apple) {
this.apple=apple;
valueMap = parseMap(apple.getRemark());
}
public Map<String,String> parseMap(String json){
try{
Map<String,Object> parseMap = objMapper.readValue(json,Map.class);
Map<String, String> resultMap = parseMap.entrySet().stream().collect(
Collectors.toMap(e -> e.getKey(), e -> String.valueOf(e.getValue())));
return resultMap;
}catch (Exception e){
e.printStackTrace();
}
return new HashMap<>();
}
public String getName(){
return this.apple.getName();
}
}
进行调试,查看最终HashMap的结构
Map<String,List<AppleMappingEntity>> convertMap = new HashMap<>();
try{
convertMap = appleList.stream()
.map(AppleMappingEntity::new)
.collect(Collectors.groupingBy(a -> a.getName()));
}catch (Exception ex){
ex.printStackTrace();
}
System.out.println(convertMap);
掌握了基础的map映射,编写的代码易读,简洁。借鉴这个场景,在数据量较多的情况,将源数据转成Map,Map在查询时高效,不用再用for去循环查找。