“左连接”两个不同的Java对象 [英] "Left join" of two different Java objects

查看:119
本文介绍了“左连接”两个不同的Java对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Object1( List< Object1> )列表和一个Object2列表( List< Object2>




  • 对象1有多个属性,包括 id

  • 对象2有多个属性,包括 object1id



我有一些SQL背景,我想要做的是在上执行左连接

object1.id = object2.object1id



这将导致代表左连接的 List< Object3>
我可以用Java硬编码算法(for ... for ...),但我确信这至少在n * m的复杂度下效率不高。



你有更好的解决方案吗? (如果可能,请使用代码,谢谢!)

解决方案

您正在尝试做一些Java并不是真正意义上的事情。



如果你能够做到这一点,你最好将属性添加到 Object1 ,这将是 Object2 的列表,其中包含与相关的对象



如果你不能,我们仍然可以选择天真地做,否则你可以尝试这样的事情:

 的HashSet<整数> hs = new HashSet< Integer>(list2.size()); 
for(Object2 o:list2){
hs.add(o.object1id);
}
// hs包含list2的所有id
List< Object1> result = new ArrayList< Object1>(); //或者另一个实现List
的类(Object1 o:list1){
if(hs.contains(o.id))
result.add(o);
}

因为必须将所有ID存储在HashSet中,所以不是很好在HashSet中添加和访问元素是O(1)(理论上),算法是O(n + m)



如果你的 Object3 class使用 Object1 Object2 构造,使用 HasMap 而不是 HashSet 其中键是id,值是object2。代码中的最后 for 循环将变为:

  Object2 o2 = hs.get(o.id); 
if(o2!= null)
result.add(new Object3(o,o2);






继续ÓscarLópez发表评论:



如果你的目标不是唯一的,你必须适应代码如下:

  HashMap< Integer,List< Object2>> hm = new HashMap< Integer,List< Object2>> ;(); 
for(Object2 o:list2){
List< Object2> l = hm.get(o.objectid1);
if(l!= null){
l.add(o);
} else {
List< Object2> l = new ArrayList< Object2>();
l.add(o);
hm。 put(o.objectid1,l);
}
// hm是map,其中每个条目包含与objectid1相关联的Object2的列表
List< Object1> result = new ArrayList< Object1> ();
for(Object1 o:list1){
List< Object2> l = hm.get(o.id);
// l包含object1id = o.id的所有Object2
for(Object2 o2:l)
result.add(new Objec t3(o,o2));
}

仍然在O(n + m),但是常数更大......


I have a list of Object1 (List<Object1>) and a list of Object2 (List<Object2>)

  • Object 1 has multiple properties, including id
  • Object 2 has multiple properites, including object1id

I have some SQL background and what I'm trying to do is to perform a "left join" on

object1.id = object2.object1id

This would result in a List<Object3> that represents the left join. I could hardcode an algorithm in Java (for... for...), but I'm sure this wouldn't be efficient with at least a complexity of n*m.

Do you have a better solution? (with code if possible, thanks!)

解决方案

You are trying to do something that Java is not really meant for.

If you are able to do it, you would be better off adding an attribute to Object1, which would be a list of Object2 containing the objects related to this.

If you can't, we still have the option of doing it naively, else you could try something like that:

HashSet<Integer> hs = new HashSet<Integer>(list2.size());
for(Object2 o : list2) {
    hs.add(o.object1id);
}
//hs contains all the ids of list2
List<Object1> result = new ArrayList<Object1>(); //Or another class implementing List
for(Object1 o : list1) {
    if(hs.contains(o.id))
        result.add(o);
}

Not pretty since you have to store all the ids in an HashSet, but since adding and accessing elements in HashSet are O(1) (theoretically), the algorithm is O(n+m)

If your Object3 class is constructed with an Object1 and Object2, use an HasMap instead of HashSet where the keys are ids, and the values object2. The last for loop in the code will become:

Object2 o2 = hs.get(o.id);
if(o2 != null)
    result.add(new Object3(o, o2);


Further to Óscar López comment:

If your objectid1 your not unique, you have to adapt the code as follows:

HashMap<Integer, List<Object2>> hm = new HashMap<Integer, List<Object2>>();
for(Object2 o : list2) {
    List<Object2> l = hm.get(o.objectid1);
    if(l != null) {
        l.add(o);
    } else {
        List<Object2> l = new ArrayList<Object2>();
        l.add(o);
        hm.put(o.objectid1, l);
}
//hm is map, where each entry contains the list of Object2 associated with objectid1
List<Object1> result = new ArrayList<Object1>();
for(Object1 o : list1) {
    List<Object2> l = hm.get(o.id);
    //l contains all Object2 with object1id = o.id
    for(Object2 o2 : l)
        result.add(new Object3(o, o2));
}

Still in O(n+m), but with bigger constants...

这篇关于“左连接”两个不同的Java对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆