Сравните более 2 (динамически решить, сколько списков) списков в Java - PullRequest
1 голос
/ 08 июля 2019
"mainList": [
    {
      "relationship": [
        "cd": "CH",
        "desc": "Child",          
       ],
        "childList": ["A", "B", "C"]
    }, {
     "relationship": [
        "cd": "SPS",
        "desc": "Spouse",
          ],
        "childList": ["A", "B", "C", "D"]
    }, {
      "relationship": [
        "cd": "MBR",
        "desc": "Member",
       ],
        "childList": ["A", "B", "C", "D", "E"]
    }, ...
]


public class MainList {
private List<Relationshipsss> relation;
private List<String> childList;

public MainList(List<Relationshipsss> relation, List<String> childList) {
    this.relation = relation;
    this.childList = childList;

}

public List<Relationshipsss> getRelation() {
    return relation;
}

public void setRelation(List<Relationshipsss> relation) {
    this.relation = relation;
}

public List<String> getChildList() {
    return childList;
}

public void setChildList(List<String> childList) {
    this.childList = childList;
}

}

public class ParentList {
private List<MainList> mainList;

public List<MainList> getMainList() {
    return mainList;
}

public void setMainList(List<MainList> mainList) {
    this.mainList = mainList;
}

}
public class Relationshipsss {
private String cd;
private String desc;

public String getCd() {
    return cd;
}
public void setCd(String cd) {
    this.cd = cd;
}
public String getDesc() {
    return desc;
}
public void setDesc(String desc) {
    this.desc = desc;
}
}

Обновлен весь класс сущностей. MainList будет иметь список отношений и дочерний список.

Я хочу сравнить childList друг с другом, взять общие и необычные значения и отделить, как и все, кому оно принадлежит.

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())));

Выше код является первым шагом вашего ответа. За это я получаю ошибку, о которой упоминал в комментарии.

Хотите вывод, как показано ниже:

  1. Ребенок, супруг, mbr = A, B, C
  2. Супруга, Mbr = D
  3. Mbr = E

1 Ответ

2 голосов
/ 08 июля 2019

Вы можете использовать потоки 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]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...