比较java中包含相同对象的两个ArrayLists

时间:2009-12-08 08:11:52

标签: java algorithm

我有一个下面给出的两个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

5 个答案:

答案 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)等等。更容易测试,更容易调试,更容易重用,更容易使用。