Java8的lambda应用: 将list分组到map的两种实现方法

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]}

 

再次仰望群里两位大佬.

你可能感兴趣的:(java)