将对象列表转换为嵌套的有序映射及有序列表

huangapple go评论166阅读模式
英文:

Convert List of objects to nested ordered map of ordered lists

问题

  1. 最终的Map<String, Map<String, Map<String, ArrayList<String>>> collect =
  2. dtoList.stream()
  3. .collect(
  4. Collectors.groupingBy(
  5. Dto::getValidationType,
  6. Collectors.groupingBy(
  7. Dto::getSource,
  8. Collectors.groupingBy(
  9. Dto::getAddress,
  10. Collector.of(
  11. TreeSet::new,
  12. (set, dto) -> set.add(dto.getError()),
  13. (set1, set2) -> { set1.addAll(set2); return set1; },
  14. ArrayList::new
  15. )
  16. )
  17. )
  18. )
  19. );
英文:

I want to convert a list of DTOs into a deep nested map.

Source format:

  1. [
  2. Dto(validationType=BASIC, source=BASE, address=A4, error=Client is a required field.),
  3. Dto(validationType=BASIC, source=BASE, address=A4, error=Client must be one of 'I', 'G' or 'W'.),
  4. Dto(validationType=BASIC, source=BASE, address=B5, error=Individuals require First and Last Names.),
  5. Dto(validationType=BASIC, source=BASE, address=D6, error=Individuals require First and Last Names.),
  6. Dto(validationType=BASIC, source=BASE, address=J7, error=First is a required field.),
  7. Dto(validationType=BASIC, source=BASE, address=L8, error=Last is a required field.),
  8. Dto(validationType=BASIC, source=BASE, address=M9, error=Name is a required field.),
  9. Dto(validationType=BASIC, source=BASE, address=N10, error=Status is a required field.),
  10. Dto(validationType=BASIC, source=BASE, address=N10, error=Status must be one of 'A' or 'P'.),
  11. Dto(validationType=BASIC, source=BASE, address=F16, error=Groups require a Group Name.)
  12. ]

Target format:

  1. {
  2. BASIC = {
  3. BASE = {
  4. A4 = [ "Client is a required field.", "Client must be one of 'I', 'G' or 'W'." ],
  5. B5 = [ "Individuals require First and Last Names." ],
  6. D6 = [ "Individuals require First and Last Names." ],
  7. J7 = [ "First is a required field." ],
  8. L8 = [ "Last is a required field." ],
  9. M9 = [ "Name is a required field." ],
  10. N10 = [ "Status is a required field." ],
  11. N10 = [ "Status must be one of 'A' or 'P'." ],
  12. F16 = [ "Groups require a Group Name." ]
  13. }
  14. }
  15. }

This code snippet:

  1. final Map<String, Map<String, Map<String, ArrayList<String>>>> collect =
  2. dtoList.stream()
  3. .collect(
  4. Collectors.groupingBy(
  5. Dto::getValidationType,
  6. Collectors.groupingBy(
  7. Dto::getSource,
  8. Collectors.groupingBy(
  9. Dto::getAddress,
  10. Collectors.mapping(
  11. Dto::getError,
  12. Collectors.collectingAndThen(
  13. Collectors.toSet(),
  14. ArrayList::new))))));

produces this map:

  1. {
  2. BASIC = {
  3. BASE = {
  4. key -> D6 = [ "Individuals require First and Last Names."],
  5. order -> B5 = [ "Individuals require First and Last Names.],
  6. not -> A4 = [ "Client must be one of 'I', 'G' or 'W'.", "Client is a required field."], <- values' original order lost
  7. preserved -> F16 = [ "Groups require a Group Name." ],
  8. -> N10 = [ "Status must be one of 'A' or 'P'.", "Status is a required field." ],
  9. -> M9 = [ "Name is a required field." ],
  10. -> L8 = [ "Last is a required field." ],
  11. -> J7 = [ "First is a required field." ]
  12. }
  13. }
  14. }

The problems are:

  1. The keys under BASE are not sorted. I know I need something like a TreeSet, but I am not sure how to collect into such a collection.
  2. The values within each list are not preserving their order. "Client is a required field." should come before "Client must be one of 'I', 'G' or 'W'.", because that is their original order.

答案1

得分: 1

  1. 你需要传入`Supplier` `mapFactory`来指定你想要收集的`Map`类型(`()->new TreeMap<>()`)。对于`TreeSet`也是一样的。
  2. 最终的`TreeMap<String, TreeMap<String, TreeMap<String, TreeSet<String>>>> collect =
  3. list.stream()
  4. .collect(
  5. groupingBy(
  6. Dto::getValidationType,
  7. TreeMap::new,
  8. groupingBy(
  9. Dto::getSource,
  10. TreeMap::new,
  11. groupingBy(
  12. Dto::getAddress,
  13. TreeMap::new,
  14. Collectors.mapping(
  15. Dto::getError,
  16. Collectors.collectingAndThen(
  17. Collectors.toSet(),
  18. TreeSet::new)
  19. )
  20. )
  21. )
  22. )
  23. );`
英文:

You need to pass in the Supplier mapFactory to specify the type of Map you wish to collect in (()->new TreeMap<>()). Same in case of TreeSet

  1. final TreeMap<String, TreeMap<String, TreeMap<String, TreeSet<String>>>> collect =
  2. list.stream()
  3. .collect(
  4. groupingBy(
  5. Dto::getValidationType,
  6. TreeMap::new,
  7. groupingBy(
  8. Dto::getSource,
  9. TreeMap::new,
  10. groupingBy(
  11. Dto::getAddress,
  12. TreeMap::new,
  13. Collectors.mapping(
  14. Dto::getError,
  15. Collectors.collectingAndThen(
  16. Collectors.toSet(),
  17. TreeSet::new)
  18. )
  19. )
  20. )
  21. )
  22. );

huangapple
  • 本文由 发表于 2023年4月6日 20:02:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75949303.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定