根据公共字段对不同类型的对象进行分组

Grouping objects of different types based on common fields

我想根据类 上字段incomeCodeendDatecodeRef 的相同内容对不同的对象类型进行分组。为了简单起见,我省略了两个 类 上的许多字段,这些字段使每个对象都是唯一的。

public class Exon  {

    private Long id;

    private IncomeCode incomeCode;

    private LocalDate endDate;

    String codeRef;

}   

public class Sup {

    private Long id;

    private IncomeCode incomeCode;

    private LocalDate startDate;

    private LocalDate endDate;

    String codeRef;

}

外显子示例:

id incomdeCode endDate codeRef
1 45 01/01/2021 4
2 21 01/01/2022 5
3 33 01/01/2023 2
4 45 01/01/2021 4

支持示例:

id incomdeCode endDate codeRef
1 45 01/01/2021 4
2 21 01/01/2022 5
3 33 01/01/2023 2

期望的结果: 列表:{ {exon1, exon4, sup1}, {exon2, sup2}, {exon3, sup3} }

我的尝试:

public Map<Object, List<Exon>> getExons() {
    Map<Object, List<Exon>> result = getSource1.stream()
            .flatMap(lp -> lp.getExons().stream())
            .collect(Collectors.groupingBy(e -> new KeyGroup(e.getIncomeCode(), e.getEndDate(), e.getCodeRef())
            ));
    return result;
  }

public Map<Object, List<Sup>> getSups() {
        Map<Object, List<Sup>> result = getSource2.stream()
                .flatMap(lp -> lp.getSups().stream())
               .collect(Collectors.groupingBy(e -> new 
KeyGroup(e.getIncomeCode(), e.getEndDate(), e.getCodeRef())));
        return result;
   }

 Map<Object, List<Exon>> exonList = getExons();
 Map<Object, List<Sup>> supList = getSups();
 Map<Object, List<List<?>>> objMap = new HashMap<>();

exonList.forEach((k, v) -> {
        if (objMap.containsKey(o)) {
            objMap.get(o).add(v);
        } else {
            List<List<?>> eList = new ArrayList<>();
            eList.add(v);
            objMap.put(o, eList);
        }

    });

    supList.forEach((o, v) -> {
        if (objMap.containsKey(o)) {
            objMap.get(o).add(v);
        } else {
            List<List<?>> eList = new ArrayList<>();
            eList.add(v);
            objMap.put(o, eList);
        }
    });

这样的事情怎么样。您可以制作另一个子class 并在这张地图

上将您的不同class 项目分组
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Solution
{

    public void sol()
    {
        List<Exon> exons = new ArrayList<>();
        List<Sup> sups = new ArrayList<>();

        List<ClassWithNeededFields> list1 = exons.stream()
        .map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
        .collect(Collectors.toList());
        
        List<ClassWithNeededFields> list2 = sups.stream()
        .map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
        .collect(Collectors.toList());
        
        list1.addAll(list2);
        
        Map<IncomeCode, List<ClassWithNeededFields>> map2 = list1.stream()
                .map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
                .collect(Collectors.groupingBy(ClassWithNeededFields::getIncomeCode));

    }

    public class Exon
    {
        private IncomeCode incomeCode;

        public IncomeCode getIncomeCode()
        {
            return null;
        }
    }

    public class Sup
    {
        private IncomeCode incomeCode;

        public IncomeCode getIncomeCode()
        {
            return null;
        }
    }

    public class IncomeCode
    {

    }

    public class ClassWithNeededFields
    {
        private IncomeCode incomeCode;

        private String otherField;

        // The other needed fields. ...

        public ClassWithNeededFields(IncomeCode incomeCode, String otherField /* The other needed fields. ... */)
        {

        }

        public IncomeCode getIncomeCode()
        {
            return this.incomeCode;
        }
    }
}

正如评论中指出的那样,如果您需要混合不同类型的对象,您得到的 List 将是 List<List<Object>>.

要按这样对它们进行分组,您可以将 collect() 终端操作与 Collectors.groupingBy() 结合使用,后者可以使用具有所需字段的 ad-hoc 构建的键对对象进行分组(incomeCodeendDatecodeRef)。构建 Map 后,您可以检索其值,即带有对象列表的 Collection,并将它们作为 List 实现的转换构造函数的输入。

List<List<Object>> listRes = new ArrayList<>(Stream.concat(listExon.stream(), listSup.stream())
        .collect(Collectors.groupingBy(obj -> {
            if (obj instanceof Exon) {
                Exon exon = (Exon) obj;
                return String.format("%s-%s-%s", exon.getIncomeCode(), exon.getEndDate(), exon.getCodeRef());
            }
            Sup sup = (Sup) obj;
            return String.format("%s-%s-%s", sup.getIncomeCode(), sup.getEndDate(), sup.getCodeRef());
        })).values());

这里还有一个link来测试上面的代码:

https://ideone.com/OSTItQ