Reputation: 182
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
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
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
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
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
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
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