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

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

Convert List of objects to nested ordered map of ordered lists

问题

最终的Map<String, Map<String, Map<String, ArrayList<String>>> collect =
    dtoList.stream()
        .collect(
            Collectors.groupingBy(
                Dto::getValidationType,
                Collectors.groupingBy(
                    Dto::getSource,
                    Collectors.groupingBy(
                        Dto::getAddress,
                        Collector.of(
                            TreeSet::new, 
                            (set, dto) -> set.add(dto.getError()), 
                            (set1, set2) -> { set1.addAll(set2); return set1; },
                            ArrayList::new
                        )
                    )
                )
            )
        );
英文:

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

Source format:

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

Target format:

{
    BASIC = {
        BASE = {
            A4 = [ "Client is a required field.", "Client must be one of 'I', 'G' or 'W'." ],
            B5 = [ "Individuals require First and Last Names." ],
            D6 = [ "Individuals require First and Last Names." ],
            J7 = [ "First is a required field." ],
            L8 = [ "Last is a required field." ],
            M9 = [ "Name is a required field." ],
            N10 = [ "Status is a required field." ],
            N10 = [ "Status must be one of 'A' or 'P'." ],
            F16 = [ "Groups require a Group Name." ]
        }
    }
}

This code snippet:

final Map<String, Map<String, Map<String, ArrayList<String>>>> collect =
    dtoList.stream()
        .collect(
            Collectors.groupingBy(
                Dto::getValidationType,
                Collectors.groupingBy(
                    Dto::getSource,
                    Collectors.groupingBy(
                        Dto::getAddress,
                        Collectors.mapping(
                            Dto::getError,
                            Collectors.collectingAndThen(
                                Collectors.toSet(),
                                ArrayList::new))))));

produces this map:

{
    BASIC = {
        BASE = {
key       ->            D6 = [ "Individuals require First and Last Names."],
order     ->            B5 = [ "Individuals require First and Last Names.],
not       ->            A4 = [ "Client must be one of 'I', 'G' or 'W'.", "Client is a required field."], <- values' original order lost
preserved ->            F16 = [ "Groups require a Group Name." ],
          ->            N10 = [ "Status must be one of 'A' or 'P'.", "Status is a required field." ],
          ->            M9 = [ "Name is a required field." ],
          ->            L8 = [ "Last is a required field." ],
          ->            J7 = [ "First is a required field." ]
        }
    }
}

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

你需要传入`Supplier` `mapFactory`来指定你想要收集的`Map`类型(`()->new TreeMap<>()`)。对于`TreeSet`也是一样的。

最终的`TreeMap<String, TreeMap<String, TreeMap<String, TreeSet<String>>>> collect =
            list.stream()
                .collect(
                    groupingBy(
                        Dto::getValidationType,
                        TreeMap::new,
                        groupingBy(
                            Dto::getSource,
                            TreeMap::new,
                            groupingBy(
                                Dto::getAddress,
                                TreeMap::new,
                                Collectors.mapping(
                                    Dto::getError,
                                    Collectors.collectingAndThen(
                                        Collectors.toSet(),
                                        TreeSet::new)
                                )
                            )
                        )
                    )
                );`
英文:

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

    final TreeMap<String, TreeMap<String, TreeMap<String, TreeSet<String>>>> collect =
        list.stream()
            .collect(
                groupingBy(
                    Dto::getValidationType,
                    TreeMap::new,
                    groupingBy(
                        Dto::getSource,
                        TreeMap::new,
                        groupingBy(
                            Dto::getAddress,
                            TreeMap::new,
                            Collectors.mapping(
                                Dto::getError,
                                Collectors.collectingAndThen(
                                    Collectors.toSet(),
                                    TreeSet::new)
                            )
                        )
                    )
                )
            );

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:

确定