Java 中 Stream 的用法
Stream的操作符大体上分为两种:中间操作符和终止操作符
对于数据流来说,中间操作符在执行制定处理程序后,数据流依然可以传递给下一级的操作符。
中间操作符包含8种(排除了parallel,sequential,这两个操作并不涉及到对数据流的加工操作)
- map(mapToInt,mapToLong,mapToDouble) 转换操作符,把比如A->B,这里默认提供了转int,long,double的操作符。
- flatmap(flatmapToInt,flatmapToLong,flatmapToDouble) 拍平操作比如把 int[]{2,3,4} 拍平 变成 2,3,4 也就是从原来的一个数据变成了3个数据,这里默认提供了拍平成int,long,double的操作符。
- limit 限流操作,比如数据流中有10个 我只要出前3个就可以使用。
- distint 去重操作,对重复元素去重,底层使用了equals方法。
- filter 过滤操作,把不想要的数据过滤。
- peek 挑出操作,如果想对数据进行某些操作,如:读取、编辑修改等。
- skip 跳过操作,跳过某些元素。
- sorted(unordered) 排序操作,对元素排序,前提是实现Comparable接口,当然也可以自定义比较器。
数据经过中间加工操作,就轮到终止操作符上场了;终止操作符就是用来对数据进行收集或者消费的,数据到了终止操作这里就不会向下流动了,终止操作符只能使用一次。
- collect 收集操作,将所有数据收集起来,这个操作非常重要,官方的提供的Collectors 提供了非常多收集器,可以说Stream 的核心在于Collectors。
- count 统计操作,统计最终的数据个数。
- findFirst、findAny 查找操作,查找第一个、查找任何一个 返回的类型为Optional。
- noneMatch、allMatch、anyMatch 匹配操作,数据流中是否存在符合条件的元素 返回值为bool 值。
- min、max 最值操作,需要自定义比较器,返回数据流中最大最小的值。
- reduce 规约操作,将整个数据流的值规约为一个值,count、min、max底层就是使用reduce。
- forEach、forEachOrdered 遍历操作,这里就是对最终的数据进行消费了。
- toArray 数组操作,将数据流的元素转换成数组。
这里只介绍了Stream,并没有涉及到IntStream、LongStream、DoubleStream,这三个流实现了一些特有的操作符,我将在后续文章中介绍到。
public class Test {
public static void main(String[] args) {
// 1、对象属性 to Map
Map<String, Integer> collect = detailList.stream()
.collect(Collectors.toMap(InboundDetail::getGoodsSku, Collectors.summingInt(InboundDetail::getFactGoodsQty)));
// 1.1、对象属性 to Map
Map<String, String> optionsMap = options.stream()
.collect(
Collectors.toMap(
optionItem -> String.valueOf(optionItem.getId()),
optionItem -> optionItem.getReflectValue()
)
);
// 2、对象属性 to List
List<Long> warehouseIdList = allocateLocationDtoList.stream()
.map(AllocateLocationDto::getWarehouseId)
.distinct()
.collect(Collectors.toList());
// 3、根据 属性 分组
Map<String, List<SendTradeInfoVO>> map = sendTradeInfoList.stream()
.collect(Collectors.groupingBy(SendTradeInfoVO::getLogisticNo));
// 3、根据 属性 分组
Map<String, Map<String, Set<String>>> checkApplicationType = detailList
.stream()
.collect(
Collectors.groupingBy(
e -> {
String descByValue = OutboundApplicationTypeEnum.getDescByValue(byPrimaryKey.getApplicationType());
return StringUtils.isEmpty(descByValue) ? "null" : descByValue;
}
, Collectors.groupingBy(
WmsOutboundApplicationDetail::getCustomerCode
, Collectors.mapping(WmsOutboundApplicationDetail::getApplicationNo, Collectors.toSet())
)
)
);
// 4、根据 属性 计数、求和
long skuCount = detailList.stream()
.map(OriginalOrderDetailVO::getGoodsSku)
.count();
Map<Long, Integer> canSaleQtyMap = warehouseStockDtos.stream().collect(Collectors.groupingBy(WarehouseStockDto::getGoodsId, Collectors.summingInt(WarehouseStockDto::getCanSale)));
int goodsQty = detailList.stream()
.mapToInt(orderDetail -> NumberUtil.getInt(orderDetail.getGoodsQty()))
.sum();
// 5、reduce 规约操作,将整个数据流的值规约为一个值,count、min、max底层就是使用reduce
BigDecimal platFormProductBearAmount = platFormAllBearInfoList.stream()
.map(amount -> {return new BigDecimal(amount.getBearAmount() == null ? "0.00" : amount.getBearAmount());})
.reduce(BigDecimal.ZERO, BigDecimal::add)
.divide(HUNDRED)
.setScale(2,RoundingMode.HALF_UP);
// 5、根据 属性 排序
List<TradeInfo> collect = goodInfos.stream()
.filter(p -> new BigDecimal(p.getTotalFee()).compareTo(BigDecimal.ZERO) > 0)
.sorted(Comparator.comparing(o -> new BigDecimal(o.getTotalFee())))
.collect(Collectors.toList());
List<AllotDetailVO> allotDetailVOList =result.getAllotDetailVOList().stream().sorted(Comparator.comparing(AllotDetailVO::getCreateTime).thenComparing(AllotDetailVO::getGoodsId)).collect(Collectors.toList());
}
}
public class Test {
public static void main(String[] args) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
String responseCharset = WebUtils.getResponseCharset(request.getContentType());
}
}