我有一个下面给出的两个ArrayList作为示例。 AccVO: compareKey,Amount字段
列表1:
AccVO[001,500]
AccVO[002,600]
AccVO[003,800]
List2:
AccVO[001,100]
AccVO[001,100]
AccVO[001,300]
AccVO[003,300]
AccVO[003,300]
AccVO[003,200]
AccVO[005,300]
AccVO[005,300]
我已对两个列表进行了排序。 我必须将两个列表与compare键进行比较,并获取List2的记录以插入数据库。
示例代码:
for(AccVO accvo1 : List1){
for(AccVO accvo2 : List2){
if(accvo1.getCmpkey().equals(accvo2.getCmpkey())){
//insert the recs into the table
}
}
}
由于我的列表大小会更大,即处理数百万条记录,我需要一些乐观的逻辑来循环记录。
提前感谢你 Prasanna
答案 0 :(得分:5)
因为您的列表已排序,您可以在两个数组中使用索引,并且每次只增加较小的键:
int i = 0,j = 0;
while (i < List1.size() && j < List2.size()){
int x = List1.get(i).getCmpKey().CompareTo(List2.get(j).getCmpKey();
if (x == 0){
//add record
j++;
}else if(x < 0){
i++;
}else{
j++;
}
}
答案 1 :(得分:3)
如果你的equals(和hashCode)实现基于getCmpkey(),你可以使用Sets。
set1 = new HashSet(list1)
set2 = new HashSet(list2)
set2.retainAll(set1);
for(AccVO a : set2) //insert
对于个体移除将具有O(1)(对于set1中的n个元素,O(n))。
答案 2 :(得分:0)
我建议在第二个列表中使用HashMap。
答案 3 :(得分:0)
如果未指定列表的类型,则应使用迭代器来遍历它们。即使您使用未由数组支持的List实现(假设您可以在O(n)时间内迭代),这将为您提供有保证的O(n)(线性)性能。
例如,如果碰巧将LinkedList作为列表类,则以下实现仍然是O(n),但使用get()索引到列表中的实现将是O(n ^ 2)。因此,如果您列出的每个大小为100万,则此实现将比索引实现快100万倍。
Iterator i1 = list1.iterator();
Iterator i2 = list2.iterator();
if (i1.hasNext() && i2.hasNext() {
AccVO v1 = i1.next();
AccVO v2 = i2.next();
while (true) {
int i = v1.getCmpKey().compareTo(v2.getCmpKey());
if (i == 0) {
// insert record into DB here
if (i2.hasNext()) {
v2 = i2.next()
} else {
break;
}
} else if (i < 0) {
if (i1.hasNext()) {
v1 = i1.next();
} else {
break;
}
} else {
if (i2.hasNext()) {
v2 = i2.next();
} else {
break;
}
}
}
}
答案 4 :(得分:0)
我想我会按照
的方式做点什么Set<Integer> goodKeys = new HashSet<Integer>();
for (AccVO a : List1)
goodKeys.add(a.getCmpkey());
for (AccVO a : List2)
if (goodKeys.contains(a.getCmpkey()))
// insert the recs into the table
然后,如果需要,我可以挂起好键列表,将第一个块提取到getKeys(List<AccVO> list)
,将余数提取到insertRecordsForKeys(Set<Integer> keys)
等等。更容易测试,更容易调试,更容易重用,更容易使用。