Вы можете использовать потоки Java и Collectors.groupingBy()
решить эту проблему:
Map<String, List<MainList>> result = mainList.stream()
.flatMap(o -> o.getChildList().stream().map(c -> Map.entry(c, o)))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
Сначала вы flatMap
все элементы в Entry
с родителем и каждым дочерним элементом. Затем вы группируете по каждому дочернему элементу.
Результатом будет карта, сгруппированная по дочерним элементам:
{
A: [{relation=[{cd='CH', desc='Child'}], childList=[A, B, C]}, {relation=[{cd='SPS', desc='Spouse'}], childList=[A, B, C, D]}, {relation=[{cd='MBR', desc='Member'}], childList=[A, B, C, D, E]}]
B: [{relation=[{cd='CH', desc='Child'}], childList=[A, B, C]}, {relation=[{cd='SPS', desc='Spouse'}], childList=[A, B, C, D]}, {relation=[{cd='MBR', desc='Member'}], childList=[A, B, C, D, E]}]
C: [{relation=[{cd='CH', desc='Child'}], childList=[A, B, C]}, {relation=[{cd='SPS', desc='Spouse'}], childList=[A, B, C, D]}, {relation=[{cd='MBR', desc='Member'}], childList=[A, B, C, D, E]}]
D: [{relation=[{cd='SPS', desc='Spouse'}], childList=[A, B, C, D]}, {relation=[{cd='MBR', desc='Member'}], childList=[A, B, C, D, E]}]
E: [{relation=[{cd='MBR', desc='Member'}], childList=[A, B, C, D, E]}]
}
После этого вы можете снова сгруппировать по списку объектов, чтобы получить карту со всеми объектами в качестве ключа и списком ваших дочерних элементов:
Map<List<MainList>, List<String>> result = mainList.stream()
.flatMap(o -> o.getChildList().stream().map(c -> Map.entry(c, o)))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
Это приведет к такой карте:
{
[{relation=[{cd='SPS', desc='Spouse'}], childList=[A, B, C, D]}, {relation=[{cd='MBR', desc='Member'}], childList=[A, B, C, D, E]}]: [D]
[{relation=[{cd='MBR', desc='Member'}], childList=[A, B, C, D, E]}]: [E]
[{relation=[{cd='CH', desc='Child'}], childList=[A, B, C]}, {relation=[{cd='SPS', desc='Spouse'}], childList=[A, B, C, D]}, {relation=[{cd='MBR', desc='Member'}], childList=[A, B, C, D, E]}]: [A, B, C]
}
Ключом здесь является сопоставление с Map.entry(c, o)
. Вы можете заменить значение записи (o
) на то, что вам нужно в качестве ключа результата. В приведенном выше примере все MainList
s используются в качестве ключа. Вы можете использовать Map.entry(c, o.getRelation())
, если вам нужно Map<List<List<Relationshipsss>>, List<String>>
. Или, если вам нужны только каждое первое отношение (Map<List<Relationshipsss>, List<String>>
), используйте Map.entry(c, o.getRelation().get(0))
. Но помните о пустых списках и, возможно, используйте Optional, чтобы обернуть это.
Если вам нужна строка desc
для каждого первого отношения в качестве ключа, вы можете использовать это:
Map<List<String>, List<String>> result = parentList.getMainList().stream()
.flatMap(o -> o.getChildList().stream().map(c -> Map.entry(c, o.getRelation().get(0).getDesc())))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
Не говоря уже о случае пустого списка отношений. Окончательный результат последней версии будет таким:
{
[Child, Spouse, Member]: [A, B, C]
[Spouse, Member]: [D]
[Member]: [E]
}