两个不同Java对象的“左连接”
我有一个Object1的列表(List<Object1>
)和一个Object2的列表(List<Object2>
)
- 对象1有多个属性,包括
id
- 对象2有多个属性,包括
object1id
我有一些SQL的背景知识,我正在尝试对其执行“左连接”
object1.id = object2.object1id
这将导致一个表示左连接的List<Object3>
。
我可以用Java硬编码一个算法,但我敢肯定,至少在n*m的复杂度下,这是不有效的
你有更好的解决办法吗?(如果可能,请提供代码,谢谢!)
# 1 楼答案
如果他们实现了一些公共接口(这将使事情变得更容易,尤其是在铸造方面),那么这是相对简单的
它仍然是O(nm),因为您必须遍历列表的两个长度才能找到要添加的元素
# 2 楼答案
一个好的解决方案可能是将Object2列表转换为映射。然后遍历Object1列表,从映射中获取Object2,最终创建连接并将结果添加到Object3列表中
# 3 楼答案
您正在尝试做一些Java并不真正适合的事情
如果你能做到这一点,最好是向
Object1
添加一个属性,这将是一个包含与this
相关的对象的Object2
列表如果你做不到,我们仍然可以选择天真地去做,否则你可以尝试这样的方式:
不太好,因为必须将所有ID存储在一个HashSet中,但由于HashSet中添加和访问元素的值是O(1)(理论上),所以算法是O(n+m)
如果
Object3
类是用Object1
和Object2
构造的,那么使用HasMap
而不是HashSet
,其中键是id,值是object2。代码中的最后一个for
循环将变成:关于Óscar López的评论:
如果你的目标不是唯一的,你必须按照以下方式调整代码:
仍然在O(n+m)中,但常数更大
# 4 楼答案
在列表中创建索引。扫描列表并填写索引:
然后,扫描列表并加入:
# 5 楼答案
如果您使用的是Java8,那么可以利用streams。它可能看起来像这样(假设
id
是要查找的Object1的id):提供的案例相当模糊,因此很难给出更详细的答案
# 6 楼答案
我相信一个
O(n*m)
解决方案是不可避免的,除非创建一个更复杂的数据结构基础设施——数据库中的高效连接是implemented使用索引、哈希、,也请记住,正确的实现应该考虑^ {CD2}}中的不止一个对象具有相同的^ {{CD3}} -在这种情况下,我的代码工作,但是所有简单地将^ {CD4}}添加到^ {{CD5}}或作为^ {< CD6}}中的键的所有解决方案都将失败。p>但实现的复杂性值得吗?如果输入列表很小,
O(n*m)
解决方案就可以了。下面是我的建议,使用好的嵌套循环:为了实现上述功能,我使用的输出对象如下所示: