“左连接”两个不同的Java对象 [英] "Left join" of two different Java objects
问题描述
我有一个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屋!