我有两个相同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++;
}
}
答案 0 :(得分:1)
如果ValueList
line_num
为String
,则按照以下方式进行比较:
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()然后你可以处理未找到的条件确保我们检查了列表中的所有值。