raw data结构:
@Data
public class GetLastProductByJobsBean implements Serializable {
private String jobNo;
private Integer operNo;
private String createBy;
private Date prodDate;
}
赋值:
GetLastProductByJobsBean b1 = new GetLastProductByJobsBean();
b1.setJobNo("JB05");
b1.setOperNo(60);
b1.setCreateBy("a");
GetLastProductByJobsBean b2 = new GetLastProductByJobsBean();
b2.setJobNo("JF00");
b2.setOperNo(10);
b2.setCreateBy("b");
GetLastProductByJobsBean b3 = new GetLastProductByJobsBean();
b3.setJobNo("JF00");
b3.setOperNo(20);
b3.setCreateBy("c");
List lists = Arrays.asList(b1, b2, b3);
方法1: 利用toMap的第三个参数(重键处理):
Map> collect =lists
.stream().collect(Collectors.toMap(x -> x.getJobNo(),
x -> {HashMap m= new HashMap<>(1);m.put(x.getOperNo(),x.getCreateBy());return m;},
(v1, v2) -> {v2.putAll(v1);return v2;}));
方法2: 用两组groupingByu并自定义Collector:
Map> collect =
lists.stream()
.collect(
Collectors.groupingBy(
GetLastProductByJobsBean::getJobNo,
Collectors.groupingBy(
k -> k.getOperNo(),
new Collector() {
@Override
public Supplier supplier() {
// 相当于做一个容器
return () -> new StringBuffer();
}
@Override
public BiConsumer accumulator() {
// 这里将真的值存放到上面的容器里
return (o, getLastProductByJobsBean) ->
o.append(getLastProductByJobsBean.getCreateBy());
}
@Override
public BinaryOperator combiner() {
//这里冲突里就用第二个吧,其实用不到,不是map的容器
return (o, o2) -> o2;
}
@Override
public Function finisher() {
return o -> o.toString();
}
@Override
public Set characteristics() {
return Collections.unmodifiableSet(
EnumSet.of(
Collector.Characteristics.UNORDERED,
Collector.Characteristics.IDENTITY_FINISH));
}
})));
最后结果:
{JF00={20=c, 10=b}, JB05={60=a}}
另一应用, 按record里面的某个field收集另一个field的集合, 如何实现 :
@Data
public static class Score{
String staff;
String dept;
int score;
public Score(String staff,String dept,int score){
this.staff=staff;
this.dept=dept;
this.score=score;
}
}
private List initData(){
List lvRet=new ArrayList<>();
lvRet.add(new Score("A1","DeptA",10));
lvRet.add(new Score("A2","DeptA",20));
lvRet.add(new Score("A3","DeptA",15));
lvRet.add(new Score("B1","DeptB",10));
lvRet.add(new Score("B2","DeptB",20));
lvRet.add(new Score("B3","DeptB",50));
lvRet.add(new Score("B4","DeptB",20));
return lvRet;
}
@Test
public void testGroupingBy(){
List lvRawData=initData();
//按Dept收集staff如何实现 ?
Map> collect=lvRawData.stream().collect(Collectors.groupingBy(Score::getDept,
Collectors.mapping(Score::getStaff,Collectors.toList())));
System.out.println(collect);
}
{DeptB=[B1, B2, B3, B4], DeptA=[A1, A2, A3]}
再次仰望群里两位大佬.