list转map 及Duplicate key

@SpringBootTest(classes = DemoApplication.class)
@Slf4j
public class ListToMapTest {

@Test

public void test() {

   List<Student> list = new ArrayList<>();

   list.add(Student.builder().id(1).code(2).name("aa").build());
   list.add(Student.builder().id(2).code(3).name("aa2").build());
   list.add(Student.builder().id(3).code(4).name("aa3").build());
   list.add(Student.builder().id(4).code(5).name("aa4").build());
   list.add(Student.builder().id(5).code(5).name("aa5").build());

   List<Student> list2 = new ArrayList<>();

   list2.add(Student.builder().id(1).code(2).name("aa").classCode("一年级").build());
   list2.add(Student.builder().id(2).code(3).name("aa").classCode("一年级").build());
   list2.add(Student.builder().id(3).code(4).name("aa").classCode("一年级").build());
   list2.add(Student.builder().id(4).code(5).name("aa4").classCode("二年级").build());
   list2.add(Student.builder().id(5).code(5).name("aa5").classCode("二年级").build());

   //id为key   value为对象student
   Map<Integer, Student> maps = list.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
   log.info(maps.toString());
   //2022-04-21 09:17:37.724  INFO 150956 --- [           main] com.example.demo.test.ListToMapTest      :
   // {1=Student(id=1, name=aa, code=2),
   // 2=Student(id=2, name=aa2, code=3),
   // 3=Student(id=3, name=aa3, code=4),
   // 4=Student(id=4, name=aa4, code=5),
   // 5=Student(id=5, name=aa5, code=5)}


   //id为key   value为某一个属性学号
   Map<Integer, Integer> codeMaps = list.stream().collect(Collectors.toMap(Student::getId, Student::getCode));
   log.info(codeMaps.toString());
   //{1=2, 2=3, 3=4, 4=5, 5=5}

   //同理 value为某一个属性姓名
   Map<Integer, String> nameMaps = list.stream().collect(Collectors.toMap(Student::getId, Student::getName));
   log.info(nameMaps.toString());
   //{1=aa, 2=aa2, 3=aa3, 4=aa4, 5=aa5}

   //如果姓名出现重复呢
   Map<Integer, String> nameMaps2 = list2.stream().collect(Collectors.toMap(Student::getId, Student::getName));
   log.info(nameMaps2.toString());
   //{1=aa, 2=aa, 3=aa, 4=aa4, 5=aa5}

    //年级为key  value为学生姓名
   //Map<String, String> classMaps = list2.stream().collect(Collectors.toMap(Student::getClassCode, Student::getName));
  // log.info(classMaps.toString());
   //报错java.lang.IllegalStateException: Duplicate key aa
   //
   //  at java.util.stream.Collectors.lambda$throwingMerger$114(Collectors.java:133)
   //  at java.util.HashMap.merge(HashMap.java:1245)
   //  at java.util.stream.Collectors.lambda$toMap$172(Collectors.java:1320)
   //  at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
   //  at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
   //  at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
   //  at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
   //  at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
   //  at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
   //  at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
   //  at com.example.demo.test.ListToMapTest.test(ListToMapTest.java:73)

   //班级名称为 key 学生名称为 value,但运行时出现了多个相同的key ,此时编译器就会抛出Duplicate key  xxxx

   //我们需要使用toMap的另外一个重载的方法!

   //Collectors.toMap(keyMapper, valueMapper, mergeFunction)
   /*
   *第三个参数是当key 发生重复时处理的方法
   *一种合并函数,用于解决两者之间的冲突与提供的相同键相关联的值到{@link Map#merge(Object, Object, BiFunction)}
   * 该合并函数有两个参数,第一个参数为当前重复key 之前对应的值,第二个为当前重复key 现在数据的值。
   * */
   //1、重复时采用后面的value 覆盖前面的value
   Map<String, String> map1 = list2.stream().collect(Collectors.toMap(Student :: getClassCode, Student :: getName,
           (value1, value2 )->{
               return value2;
           }));

   log.info(map1.toString());
   //{一年级=aa, 二年级=aa5}


   //重复时将之前的value 和现在的value拼接或相加起来;
   Map<String, String> map2 = list2.stream().collect(Collectors.toMap(Student :: getClassCode, Student :: getName,
           (key1 , key2)-> key1 + "," + key2 ));

   log.info(map2.toString());
    //{一年级=aa,aa,aa, 二年级=aa4,aa5}

   //将重复key的数据变成一个集合
   Map<String, List<String>> map3 = list2.stream().collect(Collectors.toMap(Student :: getClassCode,
           // 此时的value 为集合,方便重复时操作
           s ->  {
               List<String> studentNameList = new ArrayList<>();
               studentNameList.add(s.getName());
               return studentNameList;
           },
           // 重复时将现在的值全部加入到之前的值内
           (List<String> value1, List<String> value2) -> {
               value1.addAll(value2);
               return value1;
           }


   ));

   log.info(map3.toString());
   //{一年级=[aa, aa, aa], 二年级=[aa4, aa5]}

   //统计各个年级的人数
   Map<String, List<Student>> gmap = list2.parallelStream()
           .collect(Collectors.groupingBy(o -> o.getClassCode()));


   log.info("统计各个年级的人数"+gmap.toString());
   Map<String, Integer> map = new HashMap();
   gmap.forEach((k, v) -> {
       /*BigDecimal qmkcje = v.stream().map(o -> o.getK0bnljcgje() != null ? o.getK0bnljcgje() : BigDecimal.ZERO).reduce(BigDecimal.ZERO, BigDecimal::add);
       qmkcje = qmkcje==null ? new BigDecimal(0) : qmkcje;
       BigDecimal lastk0bnljcgje = maps.get(k)==null ? new BigDecimal(0) : maps.get(k);
       //每年1月份直接去Y_WLKXM_YB_JNCG-K0BNLJCGJE和Y_WLKXM_YB_JWCG-K0BNLJCGJE之和
       BigDecimal k0bndycgje = isFirstMon(cgybcgzeldbQuery.getCalmonthEq())?qmkcje:qmkcje.subtract(lastk0bnljcgje);
       String  g0zgsdmtext = v.stream().map(o -> o.getG0zgsdmtext()).collect(Collectors.toList()).get(0);
       CgybcgzeldbVo build = CgybcgzeldbVo.builder().g0gsdm(k).calmonth(cgybcgzeldbQuery.getCalmonthEq()).k0bndycgje(k0bndycgje).g0zgsdmtext(g0zgsdmtext).k0bnljcgje(qmkcje).build();
        v.stream().map(o -> o.getK0bnljcgje() != null ? o.getK0bnljcgje() : BigDecimal.ZERO).reduce(BigDecimal.ZERO, BigDecimal::add);
       list.add(build);*/
       int size = v.size();

       map.put(k,size);


   });

   log.info("统计各个年级的人数"+map.toString());
}

}


import lombok.Builder;
import lombok.Data;

/**

  • @author liu

  • @date 2022年04月21日 9:16
    */
    @Data
    @Builder
    public class Student {

    //id
    private int id;
    //姓名
    private String name;
    //学号
    private int code;
    //班级
    private String classCode;
    }



猜你喜欢

转载自blog.csdn.net/liuerchong/article/details/124323461