目录
一、流 (Stream) 到底是什么呢 ?
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
“集合讲的是数据,流讲的是计算! ”
注意:
①Stream 自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
二、Stream 的操作三个步骤
*创建 Stream:一个数据源(如:集合、数组),获取一个流
*中间操作:一个中间操作链,对数据源的数据进行处理
*终止操作( ( 终端操作) ):一个终止操作,执行中间操作链,并产生结果
2.1创建 Stream
Java8 中的 Collection 接口被扩展,提供了
两个获取流的方法 :
*default Stream<E> stream() : 返回一个顺序流
*default Stream<E> parallelStream() : 返回一个并行流
2.2Stream的中间操作
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”
2.2.1筛选与切片
实例:
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
list.stream()
.filter((e)->e.length()>2)
.forEach(System.out::println);
//输出结果:
aaa
bbb
ccc
ddd
----------------------------------------------------
list.stream()
.filter((e)->e.length()>2)
.skip(2)
.forEach(System.out::println);
//输出结果:
ccc
ddd
----------------------------------------------------
list.stream()
.filter((e)->e.length()>2)
.limit(2)
.forEach(System.out::println);
//输出结果:
aaa
bbb
----------------------------------------------------
List<String> list = Arrays.asList("aaa","aaa","aaa","ddd");
list.stream()
.filter((e)->e.length()>2)
.distinct()
.forEach(System.out::println);
//输出结果:
aaa
ddd
根据一个属性去重:
// 集合中有projectEquipmentCode属性重复的值
List<EquipmentDetail> allEquipmentInfo = equipmentDetailService.getAllEquipmentInfo();
// 根据projectEquipmentCode属性去重
List<EquipmentDetail> equipmentDetails = allEquipmentInfo.stream().collect(Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o->o.getProjectEquipmentCode()))), ArrayList::new)
);
Map<String, EquipmentDetail> codeEquipmentMap = equipmentDetails.stream().collect(Collectors.toMap(EquipmentDetail::getProjectEquipmentCode, Function.identity()));
根据多个属性去重:
List<EquipmentDetail> equipmentDetails = allEquipmentInfo.stream().collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(
Comparator.comparing(o->o.getProjectEquipmentCode()+ ";" + o.getId()))), ArrayList::new)
);
2.2.2映射
实例:
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
list.stream()
.map((str)->str.toUpperCase())
.forEach(System.out::println);
}
//输出结果:
AAA
BBB
CCC
DDD
----------------------------------------------------
项目中应用实例:
List<String> cinemacodes = movieCinemas.stream().map(MovieCinema::getCinemaCode).collect(Collectors.toList());
List<Map<String, Object>> resultData = cityList.stream().map(item -> {
Map<String, Object> cityToCinema = Maps.newHashMap();
cityToCinema.put("cityName", cityToCityName.get(item)==null ?"未知城市" :cityToCityName.get(item));
cityToCinema.put("cityCode", item);
cityToCinema.put("cinemaList", cityToCinemaList.get(item));
return cityToCinema;
}).collect(Collectors.toList());
2.2.3排序
List<String> list = Arrays.asList("bbb","aaa","ddd","ccc");
list.stream()
.sorted()
.forEach(System.out::println);
}
//自然排序输出结果:
aaa
bbb
ccc
ddd
----------------------------------------------------
定制排序:先按照年龄排序,如果年龄相等按照姓名排序
2.3、终止操作
终端操作会从流的流水线生成结果。其结果可以是任何不适刘的值,例如:List、Integer,甚至是void
2.3.1查找与匹配
实例:
2.3.2归约
实例:
2.3.3收集
实例:
//toList
List<String> userAllCinemaCodes = getAllMyCinemaList().stream().map(cinema -> cinema.getCinemaCode()).collect(Collectors.toList());
//toSet 可以去掉重复数据
menuResult.getResultData().stream().map(SysMenu::getShiroFlag).filter(StringUtils::isNotBlank).collect(Collectors.toSet())
//counting
List<String> list = Arrays.asList("bbb","aaa","ddd","ccc");
Long count = list.stream()
.collect(Collectors.counting());
System.out.println(count);
输出结果为:4
//joining
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
String str = list.stream()
.collect(Collectors.joining());
String str1 = list.stream()
.collect(Collectors.joining(","));
String str2 = list.stream()
.collect(Collectors.joining(",","[","]"));
System.out.println(str);
System.out.println(str1);
System.out.println(str2);
输出结果为:
aaabbbcccddd
aaa,bbb,ccc,ddd
[aaa,bbb,ccc,ddd]
//grooupingBy
分组返回的结果:Map(key,value),key为分组的属性,结果为value
Map<String, List<VoucherSale>> codesListgroup = voucherSales.stream().collect(Collectors.groupingBy(VoucherSale::getInviteCode));
List<VoucherSale> voucherSaleList = codesListgroup.get(sysUser.getInviteCode());
// 实例应用
List<GroupModel> groupModelList = groupDao.selectGroups();
List<GroupStuModel> groupStuModelList = groupStuDao.selectGroupStu();
List<GroupApproveModel> groupApproveModelList =groupApproveDao.selectGroupApprove();
Map<String, List<GroupApproveModel>> approveCollect = groupApproveModelList.stream().collect(Collectors.groupingBy(GroupApproveModel::getGroupId));
Map<String, List<GroupStuModel>> stuCollect = groupStuModelList.stream().collect(Collectors.groupingBy(GroupStuModel::getGroupId));
groupModelList.stream().forEach(groupModel ->
{
groupModel.setApproveCount(approveCollect.get(groupModel.getId()) == null?0:approveCollect.get(groupModel.getId()).size());
groupModel.setStuCount(stuCollect.get(groupModel.getId())== null?0:stuCollect.get(groupModel.getId()).size());
groupModel.setUserName(allusersDao.selectById(groupModel.getUserId())== null?"":allusersDao.selectById(groupModel.getUserId()).getUserName());
});
多级分组: