按字段组合并2对象列表

发布时间:2020-07-06 06:31

我有2个对象列表,这些对象来自数据库中具有相同主键集的2个表。

public class ObjA {
    private String pk1;
    private String pk2;
    private String pk3;
    private String data1;
    private String data2;
}

public class ObjB {
    private String pk1;
    private String pk2;
    private String pk3;
    private String data1;
}

如果他们具有相同的主键集,我想将data1中的字段ObjB合并到data1中的字段ObjA中。

我正在使用此代码,但由于复杂度O(n 2

,我认为这是长代码而不是效率
List<ObjA> listA = new ArrayList<>(); //TODO: init
List<ObjB> listB = new ArrayList<>(); //TODO: init

listA.forEach(a -> {
    Predicate<ObjB> objBFilter =
        b -> a.getPk1().equals(b.getPk1())
        && a.getPk2().equals(b.getPk2())
        && a.getPk3().equals(b.getPk3());
    Optional<ObjB> bOpt =
            listB.stream().filter(objBFilter).findFirst();
    if (bOpt.isPresent()) {
        a.setData1(bOpt.get().getData1());
    }
});

在Java 8中,有什么方法可以轻松地完成此任务吗?

回答1

正如我在评论中建议的那样,可以通过创建一个哈希图来完成此操作,该哈希图的主键是一个映射键,而O(n)或仅仅是Obj就是它的值。如您在评论中所注意到的,如果list包含(pk1,pk2,pk3)=(“ 1”,“ 23”,“ 4”)和(“ 1”,“ 2”,“ 34” ”)。您也可以轻松解决此问题。一种方法是创建一个单独的类,以将键保存在3个字段中。但是,如果您确定这些主键始终是数字,或者只是确定其中某些字符永远不会出现,则可以将该字符用作分隔符。

data1

现在您有了包含其他数据的地图,可以在固定时间内访问它并追加到List<ObjA> listA = new ArrayList<>(); List<ObjB> listB = new ArrayList<>(); Map<String, String> mapping = new HashMap<>(); //storing concatenation of keys and data1 listB.forEach(b-> mapping.put(b.getPk1()+','+b.getPk2()+','+b.getPk3(), b.getData1())); //using ',' as a separator here. s。

ObjA