Save Load
GitHub 切换暗/亮/自动模式 切换暗/亮/自动模式 切换暗/亮/自动模式 返回首页

Java 中 Stream 的用法

Java 中 Stream 的用法

1、操作符

Stream的操作符大体上分为两种:中间操作符和终止操作符

1.1、中间操作符

对于数据流来说,中间操作符在执行制定处理程序后,数据流依然可以传递给下一级的操作符。

中间操作符包含8种(排除了parallel,sequential,这两个操作并不涉及到对数据流的加工操作)

  1. map(mapToInt,mapToLong,mapToDouble) 转换操作符,把比如A->B,这里默认提供了转int,long,double的操作符。
  2. flatmap(flatmapToInt,flatmapToLong,flatmapToDouble) 拍平操作比如把 int[]{2,3,4} 拍平 变成 2,3,4 也就是从原来的一个数据变成了3个数据,这里默认提供了拍平成int,long,double的操作符。
  3. limit 限流操作,比如数据流中有10个 我只要出前3个就可以使用。
  4. distint 去重操作,对重复元素去重,底层使用了equals方法。
  5. filter 过滤操作,把不想要的数据过滤。
  6. peek 挑出操作,如果想对数据进行某些操作,如:读取、编辑修改等。
  7. skip 跳过操作,跳过某些元素。
  8. sorted(unordered) 排序操作,对元素排序,前提是实现Comparable接口,当然也可以自定义比较器。

1.2、终止操作符

数据经过中间加工操作,就轮到终止操作符上场了;终止操作符就是用来对数据进行收集或者消费的,数据到了终止操作这里就不会向下流动了,终止操作符只能使用一次。

  1. collect 收集操作,将所有数据收集起来,这个操作非常重要,官方的提供的Collectors 提供了非常多收集器,可以说Stream 的核心在于Collectors。
  2. count 统计操作,统计最终的数据个数。
  3. findFirst、findAny 查找操作,查找第一个、查找任何一个 返回的类型为Optional。
  4. noneMatch、allMatch、anyMatch 匹配操作,数据流中是否存在符合条件的元素 返回值为bool 值。
  5. min、max 最值操作,需要自定义比较器,返回数据流中最大最小的值。
  6. reduce 规约操作,将整个数据流的值规约为一个值,count、min、max底层就是使用reduce。
  7. forEach、forEachOrdered 遍历操作,这里就是对最终的数据进行消费了。
  8. toArray 数组操作,将数据流的元素转换成数组。

这里只介绍了Stream,并没有涉及到IntStream、LongStream、DoubleStream,这三个流实现了一些特有的操作符,我将在后续文章中介绍到。

2、Example

2.1、stream

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());

    }
}

2.2、HttpServletRequest

public class Test {
    public static void main(String[] args) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        String responseCharset = WebUtils.getResponseCharset(request.getContentType());
    }
}

2.3、