本来打算自己想一个业务场景来,实在没想到,先说一下现实业务:
淘宝卖家的商品都会买一些关键词(一个商品可买多个),然后淘宝按照商家出价对关键词搜出来的商品进行排序。淘宝则记录每个商品下按照关键词搜索对应的展现量,点击量,点击率,并且区分pc端,移动端。
List<RtRptResultEntityDTO> list=new ArrayList<RtRptResultEntityDTO>();
RtRptResultEntityDTO a=new RtRptResultEntityDTO();
a.setBidwordid("1");
a.setImpression("5");
a.setClick("5");
a.setSource("1");//PC站外
list.add(a);
RtRptResultEntityDTO x=new RtRptResultEntityDTO();
x.setBidwordid("1");
x.setImpression("6");
x.setClick("6");
x.setSource("1");
list.add(x);
RtRptResultEntityDTO c=new RtRptResultEntityDTO();
c.setBidwordid("1");
c.setImpression("5");
c.setClick("8");
c.setSource("2");//PC站内
list.add(c);
RtRptResultEntityDTO b=new RtRptResultEntityDTO();
b.setBidwordid("2");
b.setImpression("8");
b.setClick("8");
b.setSource("4");//移动站外
list.add(b);
RtRptResultEntityDTO d=new RtRptResultEntityDTO();
d.setBidwordid("4");
d.setImpression("8");
d.setClick("8");
d.setSource("5");//移动站内
list.add(d);
for(int i = 0;i < list.size();i++){
System.out.println(list.get(i).getBidwordid());
}
==第一步==
//Java8流操作,先按照关键词id分组得到形如(key1:(a1,b1,c1;a2,b2,c2);key2:(x1,y1,z1,...))的map
Map<String, List<RtRptResultEntityDTO>> map=list.stream().collect(groupingBy(RtRptResultEntityDTO::getBidwordid));
//定义返回结果list
List<ResultList> result = new ArrayList<>(KeywordList.size);
//遍历关键词list
for(Keyword keyword : KeywordList){
==第二步==
//获取同一关键词不同流量来源的列表
List<RtRptResultEntityDTO> list1= map.get(keyword.getBidwordid);
==第三步==
//再按照流量来源分组
Map<String, RtRptResultEntityDTO> map2=list1.stream().collect(Collectors.toMap(RtRptResultEntityDTO::getSource, Function.identity()));
int impression = 0;
int click = 0;
BigDecimal zero = BigDecimal.ZERO;
if ("1,2".equals(source)) {//流量来源为PC
==第四步==
for (Map.Entry<String, RtRptResultEntityDTO> cc : map2.entrySet()) {
if (cc.getKey().equals("1") || cc.getKey().equals("2")) {
impression = impression + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getImpression()) ? "0" : cc.getValue().getImpression());
click = click + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getClick()) ? "0" : cc.getValue().getClick());
cost = cost + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getCost()) ? "0" : cc.getValue().getCost());
}
}
} else if ("4,5".equals(source)) {//流量来源为移动
for (Map.Entry<String, RtRptResultEntityDTO> cc : map2.entrySet()) {
if (cc.getKey().equals("4") || cc.getKey().equals("5")) {
impression = impression + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getImpression()) ? "0" : cc.getValue().getImpression());
click = click + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getClick()) ? "0" : cc.getValue().getClick());
cost = cost + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getCost()) ? "0" : cc.getValue().getCost());
}
}
} else if ("SUMMARY".equals(source)) {//流量来源为汇总
for (Map.Entry<String, RtRptResultEntityDTO> cc : map2.entrySet()) {
if (cc.getKey().equals("1") || cc.getKey().equals("2") || cc.getKey().equals("4") || cc.getKey().equals("5")) {
impression = impression + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getImpression()) ? "0" : cc.getValue().getImpression());
click = click + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getClick()) ? "0" : cc.getValue().getClick());
cost = cost + Integer.valueOf(StringUtils.isEmpty(cc.getValue().getCost()) ? "0" : cc.getValue().getCost());
}
}
}
ResultList data = new ResultList();
data.setImpression(impression);
data.setClick(click);
result.add(data);
}
return result;
返回结果即为最终统计结果。
分析过程:
第一步:先将列表list按照id分组,得到形如(id1:(a1,b1,type1;a2,b2,type2;a3,b3,type3;a4,b4,type4);id2:(x1,y1,type1,…))的map1;
第二步:根据id遍历map,得到同一id的不同类型数据列表list1;
第三步:再次将列表list1按照类型type分组,得到(type1:a1,b1,type1)的map2;
第四步:遍历map2,按照类型不同进行求和。