java_learner
java_learner

Reputation: 182

Comparing two ArrayLists

I have two arrayList of the same Type and I want to compare the two based on a particular attribute in the ValueList. 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

I want to compare both the list based on line_num and create another arraylist Result and if the line_num is present in ValueList A but not in ValueList B, then the value field in the Result has to have a -1. Result should be like;

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

I am not able to write the 'Not Found' Condition. Could someone please help me?

My code

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);
        }
    }
}

Updated Code which works:

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++;
 }      

}

Upvotes: 0

Views: 318

Answers (6)

Adrian Shum
Adrian Shum

Reputation: 40036

As I asked in the comment, what if a row contained in B but not A? are you going to simply ignore that? what if you have 2 items in A that have same line_num while there is only 1 item in B with such line_num? What if there are 2 matching items in B for an item in A?

You have to be clear on what you are trying to do.

From your code, it seems that whenever there is a matching "line_num" in list B, you will insert the "key+value" as a result in the result list.

if so, making use of a Set which contains all the line numbers in bList is easiest and most reasonable.

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

after you have the set, everything is easy, in psuedo code, it looks like this:

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

Upvotes: 1

Maxime Ch&#233;ramy
Maxime Ch&#233;ramy

Reputation: 18831

From an algorithm point of view:

Add a boolean variable found that equals to false before the start of the inner loop. Then when you found one, you set it to true.

After the loop, you test the variable found and if it's false, you add -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(...)
    }
}

However, Java allows better solutions, see the other answers for that.

But, if the lists are sorted like in your example, you have better algorithms. You can use a single while loop and 2 indexes (one per list). The complexity will drop from O(N*M) to 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++;
   }      
}

Upvotes: 1

M Abbas
M Abbas

Reputation: 6479

You can override the method equals in ValueList:

 @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();
    }

Then:

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);
}

Upvotes: 1

John
John

Reputation: 281

You should check the first value in List 1 the each and every values, if a value is not matching then have a condition to check is the list.hasNext() then you can handle the not found condition making sure that the we have checked all the values in the list.

Upvotes: 0

Michael Lang
Michael Lang

Reputation: 3992

Your ValueList data should probably define its equals() method properly, by comparing getKey() values. Then you can use

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);
}

Upvotes: 0

darijan
darijan

Reputation: 9775

If ValueList line_num is String then compare like this:

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

Otherwise, implement equals() method in ValueList class and compare like:

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;
    }

Upvotes: 1

Related Questions