在Java中比较2个以上(动态决定列表数量)列表

时间:2019-07-08 11:54:25

标签: java arrays object collections

"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 个答案:

答案 0 :(得分:2)

您可以使用Java Streams和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作为键。如果需要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]
}