Java流(stream)的使用
下面来介绍下java流的使用,希望能帮助到大家。
流程:
原集合 —> 流 —> 各种操作(如:过滤、分组、统计、排序等等...) —> 终端操作,然后再将流转为集合类型。
流分为两种:一种是串行流stream(); 和并行流parallelStream();
排序
降序
List<StudentInfo> studentsSortName = studentList.stream().sorted(Comparator.comparing(StudentInfo::getAge).reversed()).collect(Collectors.toList());
升序
List<StudentInfo> studentsSortName = studentList.stream().sorted(Comparator.comparing(StudentInfo::getAge)).collect(Collectors.toList());
对象排序
//根据Dict对象的sort字段降序排序 dictList.sort(Comparator.comparing(Dict::getSort).reversed()); //根据Dict对象的sort字段升序排序 dictList.sort(Comparator.comparing(Dict::getSort));
去重
根据 List 中 Object 某个属性去重
List<BlogHistory> filterList = list.stream().collect(collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(BlogHistory::getArticleId))), ArrayList::new));
根据List 中 Object 多个属性去重
List<BlogHistory> filterList1 =list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getArticleId() + ";" + o.getMemberId()))), ArrayList::new));
去重集合中的字符,返回不重复属性集合数据(集合字符)
List<String> memberSearchHistoryList = memberSearchHistories.stream().map(MemberSearchHistory::getKeyWord).distinct().collect(Collectors.toList());
返回数据格式如下:
{
"msg": "操作成功",
"code": 200,
"data": [
"坡头",
"安详",
"更为",
"和任务给",
"官网",
"个问题我",
"发斯蒂芬"
]
}
筛选
条件筛选数据
年龄在40岁以上的用户
List<User> filterList = list.stream().filter(user -> user.getAge() >= 40).collect(toList());
根据多条件筛选数据
List<Orders> newOrder = orders.stream().filter(o -> o.getOrderStatus() == 1 || o.getOrderStatus() == 9).collect(toList());
filter里面,->箭头后面跟着的是一个boolean值,可以写任何的过滤条件,就相当于sql中where后面的东西
查list集合中抽取多个id [1,2,3,4,5]
List<Long> shopIds = shopInfoList.stream().map(o -> o.getShopId()).collect(Collectors.toList());
过滤后循坏的给符合条件的属性添加数据
ordersData.stream().filter(o -> o.getMarketId().equals(marketId)).forEach(m -> m.setSalesFirst(true));
不做过滤添加
orders.stream().forEach(o -> o.setDistanceFormat(o.getDistance() > 1000 ? StringUtils.formatDouble(o.getDistance() / 1000d) + "公里" : o.getDistance() + "米"));
过滤空字符
List<ServeRegional> newOrder = serveRegionalList.stream().filter(o -> o.getAdviserId().trim().isEmpty()).collect(toList());
List<String> cIds = customerIds.stream().filter(str -> !str.trim().isEmpty()).collect(Collectors.toList());
查找
查找某一属性最大值
最小 使用(minBy)
Optional<Users> max = list.stream().collect(Collectors.maxBy(Comparator.comparing(Users::getAge)));
获取集合中某个属性的最小值那条记录
Rider rider = riderList.stream().min(Comparator.comparing(Rider::getNumberOfOrder)).get();
查询多少条
limit
List<MemberSearchHistory> limitList = filterList.stream().limit(8).collect(toList());
skip
与limit恰恰相反,skip的意思是跳过,也就是去除前n个元素。
检测年龄是否大于18岁的信息,有则true 否则false
boolean isAdult = list.stream().allMatch(user -> user.getAge() >= 18);
检测集合中是否有湛江的用户
boolean isLSJ = list.stream().noneMatch(user -> user.getAddress().contains("湛江"));
返回true则没有 false则有
查询是否包含
mobileApplies.stream().anyMatch(w->w.getActivationState() == ActivationEnum.ED_ACTIVATION.getValue())
找到第一条数据
Optional<Orders> fristUser = list.stream().findAny();
找到任意一条数据
Optional<User> anyUser = list.stream().findAny();
分割
将集合数据以逗号拼接起来
List<String> flatList = new ArrayList<>();
flatList.add("唱,跳");
flatList.add("rape,篮球,music");
flatList = flatList.stream().map(s -> s.split(",")).flatMap(Arrays::stream).collect(toList());
System.out.println(flatList);
打印如下:
[唱, 跳, rape, 篮球, music]
这里原集合中的数据由逗号分割,使用split进行拆分后,得到的是Stream<String[]>,字符串数组组成的流,要使用flatMap的
字符串拼接,将集合中的某个元素的所有数据进行替换
String names = list.stream().map(Orders::getReceiverName).collect(Collectors.joining(", "));
返回数据如下:
{
"msg": "陈某, 陈大大, 佛挡杀佛, 发的发生的, 佛挡杀佛",
"code": 200
}
统计
计算某个属性的总和
long count = ordersList.stream().sorted(Comparator.comparing(Orders::getOrderNo)).collect(Collectors.counting());
年龄的总和
Integer totalAge = list.stream().collect(Collectors.summingInt(Users::getAge));
计算总金额,类型(BigDecimal)
BigDecimal sum = list.stream() .map(Users::getMoney).reduce(BigDecimal.ZERO,BigDecimal::add);
求年龄平均值
double avgAge = list.stream().collect(Collectors.averagingInt(Orders::getAge));
计算总数据总和
Long count = list.stream().collect(Collectors.counting());
简写
long count = list.stream().count();
一次性得到元素的个数、总和、最大值、最小值
IntSummaryStatistics statistics = list.stream().collect(Collectors.summarizingInt(User::getAge));
统计个城市的用户个数有多少
Map<String, Long> cityCountMap = list.stream().collect(Collectors.groupingBy(Users::getAddress,Collectors.counting()));
条件统计(外卖订单有多少)
long takeawayOrderData = ordersList.stream().filter(s -> s.getFreightId().equals(0)).count();
多条件的话使用双杆
long afterSaleOrderSum = ordersList.stream().filter(s -> s.getOrderStatus().equals(4) || s.getOrderStatus().equals(6)).count();
附加:
Integer takeaway = ordersList.stream().filter(s -> s.getFreightId().equals(1)).collect(Collectors.summingInt(Orders::getFreightId));
分组
根据某个属性分组,一级分组
返回的是map结构,key为分组名,组名带着数据
Map<String, List<Orders>> receiverName = list.stream().collect(Collectors.groupingBy(Orders::getReceiverName));
根据多个属性分组,二级分组
Map<String, Map<Long, List<Orders>>> group = list.stream().collect(Collectors.groupingBy(Orders::getReceiverName,
Collectors.groupingBy(Orders::getMemberId)));
根据某个属性分组并统计那个属性的数量
Map<String, Long> cityCountMap = list.stream().collect(Collectors.groupingBy(Orders::getReceiverName,Collectors.counting()));
根据某个属性过滤再进行分区统计
分区与分组的区别在于,分区是按照 true 和 false 来分的,因此partitioningBy 接受的参数的 lambda 也是 T -> boolean
Map<String,Long> map = list.stream().filter(user -> user.getAge() <= 30)
.collect(Collectors.groupingBy(User::getAddress,Collectors.counting()));
mobileApplies.stream().anyMatch(w->w.getActivationState() == ActivationEnum.ED_ACTIVATION.getValue())