我有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中,有什么方法可以轻松地完成此任务吗?
正如我在评论中建议的那样,可以通过创建一个哈希图来完成此操作,该哈希图的主键是一个映射键,而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