如何使用 Stream 对集合中属性按照另外一个属性拆分

tagIdList channel         tagId  代购数量 现货数量  
 12,13     "现货"     ->    12        1         0  
 13,14     "代购"           13        1         1  
                           14        0         1

最初的想法是上面的这样的, 但是想了半天也没有结果, 于是拆解为下面的

tagIdList  channel       tagId   channel       tagId   代购数量     现货数量  
  12,13     "现货"   ->    12       10     ->    12        1         0
  13,14     "代购"         13       10           13        1         1  
                          13       11           14        0         1  
                          14       11

第二步到第三步可以用 groupBy + count 解决, 但是第一步到第二部实在是想不到了, 各位大佬有没有什么好的想法

阅读 4k
2 个回答

对,其实就是如@_TNT_ 说得那样的操作流程,其实这个问题本质上就是一个streamflatMap操作,我个人喜欢叫 压平
代码大体实现如下面所示

@Data  
@AllArgsConstructor  
public class YourData {  
  
    private List<Long> tagIdList;  
    private String channel;  
  
    public Stream<PairData> toPair() {  
        return this.tagIdList.stream().map(tagId -> new PairData(tagId, this.channel));  
    }  
  
    @Data  
    @AllArgsConstructor  
    class PairData {  
        private Long tagId;  
        private String channel;  
    }  
  
    public static void main(String[] args) {  
      List<YourData> dataList = new ArrayList<>();  
  
      dataList.add(new YourData(Arrays.asList(12l, 13l), "现货"));  
      dataList.add(new YourData(Arrays.asList(13l, 14l), "代购"));  
  
      Map<Long, Long> map = dataList.stream()  
                                    .flatMap(YourData::toPair)  
                                    .collect(Collectors.groupingBy(  
                                            PairData::getTagId,  
                                            Collectors.counting()));
  }  
}

总的来说就是换成了tagIdchannel之间映射关系的stream,然后再做groupBy,如果你不喜欢自己创建这个PairData,可以用一个Java8函数式编程的增强库vavr,里面有元组概念Tuple,也支持更多stream上更多的操作,所以这个PairData类你可以用元组去代替它,比如

    Tuple2<Long, String> java8 = Tuple.of(12, "现货");

以上仅供参考哈

第一步到第二步,先把输入 map 成 tagId 和 channel 的 List,再 flatMap 打开就行了
讲真这种不用stream做就行了,stream写太复杂出问题debug不是很方便

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题