groupingBy的实际应用
描述
对于实体A和B, 两者是多对多的关系, 表中column类似xxx_A, xxx_B, xx_A, xx_B, 现因历史原因该表以B为维度存储数据, 前端展示时只是以_A, _B作区分来展示
问题
列表页每一条同样对应详情, 展示B的页面无问题, 但是展示A的页面时, 出现多条记录指向同一详情的现象, 并且多条记录的数据汇总才与详情中的内容对应.
解决
在存数据时对数据进行汇总处理, 这里采用Stream进行group操作, 代码如下:
public class Main {
public static void main(String[] args) {
List<Buss> bussList = new ArrayList<>();
bussList.add(new Buss("a",10,0.3, 1, 1));
bussList.add(new Buss("b",3,0.8, 2, 2));
bussList.add(new Buss("c",5,2.0, 3,3));
bussList.add(new Buss("b",30,3.2, 4,4));
bussList.add(new Buss("c",20,0.1, 3,5));
bussList.add(new Buss("c", 10, 1.5, 3,3));
bussList.add(new Buss("c", 16, 2.5, 7,7));
List<Buss> st = new ArrayList<>();
bussList.stream()
// 模拟需要name和another两个字段确定一条记录的情况
.collect(Collectors.groupingBy(Buss::groupField))
.forEach((k,v) -> {
Optional<Buss> sum = v.stream().reduce((v1,v2) -> {
v1.setCount(v1.getCount()+v2.getCount());
v1.setValue(v1.getValue()+v2.getValue());
return v1;
});
st.add(sum.orElse(new Buss("other", 0, 0.0, 0, -1)));
});
System.out.println(st);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Buss {
private String name;
private int count;
private double value;
private int another;
private int id;
public String groupField() {
return this.name + this.another;
}
@Override
public String toString() {
return "\nBuss{" +
"name='" + name + '\'' +
", count=" + count +
", value=" + value +
", another=" + another +
", id=" + id +
"}";
}
}
运行会输出:
Buss{name='c', count=35, value=3.6, another=9, id=3},
Buss{name='b', count=3, value=0.8, another=2, id=2},
Buss{name='a', count=10, value=0.3, another=1, id=1},
Buss{name='b', count=30, value=3.2, another=4, id=4},
Buss{name='c', count=16, value=2.5, another=7, id=7}