比较两个ArrayLists

时间:2013-07-08 09:01:57

标签: java list arraylist

我有两个相同Type的arrayList,我想根据ValueList中的特定属性来比较这两个。 值列表

ValueList A contains
1,10,5,
2,20,3
3,40,5,
4,60,8

ValueList B contains
2,20,3
3,40,5

我想比较基于line_num的列表并创建另一个arraylist Result,如果line_num存在于ValueList A但不存在于ValueList B中,那么Result中的value字段必须为-1。结果应该是;

Result
10,-1
20,3
40,5,
60,-1

我无法写出“未找到”条件。有人可以帮助我吗?

我的代码

List<Result> result= new ArrayList<Result>();
for(ValueList data1: valueListA) {
    for (ValueList data2: valueListB) {
        Result inter = new Result();
        if(data1.getLine_num==data2.getLine_num) {
            inter.setKey(data1.getKey());
            inter.setValue(data1.getValue());
            result.add(inter);
        }
    }
}

更新后的代码:

public static  List<Result> result;= new ArrayList<Result>();
    ....

  int i1 = 0,int i2 = 0;
  Result inter = new Result();
  while (i1 < valueListA.size() && i2 < valueListB.size()) {
  ValueList data1 = valueListA.get(i1);
  ValueList data2 = valueListB.get(i2);
  if (data1.getLine_num == data2.getLine_num) {
  // Add the result.      
  result= new ArrayList<Result>();

  inter.setValue(data1.getValue());
  inter.setKey(data1-getKey())
  result.add(inter);
  i1++;
  i2++;
 } else if (data1.getLine_num < data2.getLine_num) {
 result= new ArrayList<Result>();
  // Add -1 because the data was not in valueListB.
   inter.setValue(data1.getValue());
  inter.setKey(-1);
  result.add(inter);
  i1++;
  } else {
   i2++;
 }      

}

6 个答案:

答案 0 :(得分:1)

如果ValueList line_numString,则按照以下方式进行比较:

if(data1.getLine_num.equals(data2.getLine_num)) 

否则,在equals()类中实现ValueList方法并比较如下:

if (data1.equals(data2)) 

public class ValueList {
    ....

    @Override
    public boolean equals(Object o) {
         if (!(o instanceof ValueList)) 
             return false;

         ValueList other= (ValueList)o;

         if (this.line_num != other.line_num)
            return false;

         ....
         return true;
    }

答案 1 :(得分:1)

从算法的角度来看:

在内循环开始之前添加一个等于found的布尔变量false。然后,当您找到一个时,将其设置为true

在循环之后,您测试变量found,如果它是假,则添加-1。

List<Result> result= new ArrayList<Result>();
for(ValueList data1: valueListA){
    boolean found = false;
    for (ValueList data2: valueListB){
        Result inter= new Result();
        if(data1.getLine_num==data2.getLine_num){
           inter.setKey(data1.getKey());
           inter.setValue(data1.getValue());
           result.add(inter);
           found = true;
           break;
        }
    }
    if (!found) {
       result.add(...)
    }
}

但是,Java允许更好的解决方案,请参阅其他答案。

但是,如果列表按照您的示例进行排序,则您有更好的算法。您可以使用单个while循环和2个索引(每个列表一个)。复杂性将从O(N * M)下降到O(N + M)。

int i1 = 0;
int i2 = 0;
while (i1 < valueListA.size() && i2 < valueListB.size()) {
   ValueList data1 = valueListA[i1];
   ValueList data2 = valueListB[i2];
   if (data1.getLine_num == data2.getLine_num) {
      // Add the result.
      i1++;
      i2++;
   } else if (data1.getLine_num < data2.getLine_num) {
      // Add -1 because the data was not in valueListB.
      i1++;
   } else {
      i2++;
   }      
}

答案 2 :(得分:1)

您可以在ValueList:

中覆盖等于equals的方法
 @Override
    public boolean equals(Object obj) {
         if (obj == null)
            return false;
         if (obj == this)
            return true;
         if (!(obj instanceof ValueList))
            return false;

         ValueList other= (ValueList) obj;

         return other.getLineNum() == this.getLineNum();
    }

然后:

List<Result> result= new ArrayList<Result>();
for(ValueList data1: valueListA) {
    Result inter= new Result();
    if (valueListB.contains(data1)) {
         inter.setKey(data1.getKey());
    } else {
         inter.setKey("-1" /* or -1 */);
    }
    inter.setValue(data1.getValue());
    result.add(inter);
}

答案 3 :(得分:1)

正如我在评论中所说,如果B中包含一行但不包含A,该怎么办?你会忽略那个吗?如果A中有2个具有相同line_num的项目,而B中只有1个具有此类line_num的项目,该怎么办?如果B中的项目中有2个匹配的项目,怎么办?

你必须清楚你想要做什么。

从您的代码中看来,只要列表B中存在匹配的“line_num”,您就会在结果列表中插入“key + value”。

如果是这样,使用包含bList中所有行号的Set是最简单和最合理的。

Set<Integer> bLineNums =new HashSet<Integer>();
for (ValueList v : bList) {
  bLineNums.add(v.getLineNum());
}

拥有该集后,一切都很简单,在伪代码中,它看起来像这样:

for (ValueList a : aList) {
  if (bLineNums.contains(a.getLineNum)) {
    result.add(new Result(a.getKey(), a.getValue()));
  }
}

答案 4 :(得分:0)

您的ValueList数据可能应该通过比较equals()值来正确定义其getKey()方法。然后你可以使用

List<Result> result= new ArrayList<Result>();
for (ValueList data1: valueListA){
    Result inter = new Result();
    inter.setKey(data1.getKey());
    if (valueListB.contains(data1)) {
        inter.setValue(data1.getValue());
    } else {
        inter.setValue(-1);
    }
    result.add(inter);
}

答案 5 :(得分:0)

你应该检查列表1中的每个值的第一个值,如果一个值不匹配那么有一个条件要检查是list.hasNext()然后你可以处理未找到的条件确保我们检查了列表中的所有值。