给定以下数据类型Testcase
(XQuery
,Testpath
,FirstInputFile
,SecondInputFile
,Expected
)
如何正确删除重复项。
重复的定义:
如果FirstInputFile
已在列表中SecondInputFile
,则反之亦然。
这是Testdata
tcs.add(new HeaderAndBodyTestcase("XQ 1", "/1", "FAIL", "FAIL2", "FAILED"));
tcs.add(new HeaderAndBodyTestcase("XQ 1", "/1", "FAIL2", "FAIL", "FAILED"));
tcs.add(new HeaderAndBodyTestcase("XQ 2", "/2", "FAIL4", "FAIL3", "FAILED2"));
tcs.add(new HeaderAndBodyTestcase("XQ 2", "/2", "FAIL3", "FAIL4", "FAILED2"));
这是函数
protected void deleteExistingDuplicatesInArrayList(final ArrayList<HeaderAndBodyTestcase> list) {
for (int idx = 0; idx < list.size() - 1; idx++) {
if (list.get(idx).firstInputFile.equals(list.get(idx).secondInputFile)
|| (list.get(idx + 1).firstInputFile.equals(list.get(idx).firstInputFile)
&& list.get(idx).secondInputFile.equals(list.get(idx + 1).secondInputFile)
|| (list.get(idx).firstInputFile.equals(list.get(idx + 1).secondInputFile)
&& list.get(idx).secondInputFile.equals(list.get(idx + 1).firstInputFile)))) {
list.remove(idx);
}
}
}
这个解决方案已经有效,但看起来很糟糕,那么有更好的解决方案吗?
答案 0 :(得分:2)
使用比较器将所有内容放入Set
,如果您确实需要List(而不是Collection),则从该集创建一个列表
Set<HeaderAndBodyTestcase> set = new Hashset<>(list);
答案 1 :(得分:1)
鉴于你相当特殊的平等&#34;约束,我认为最好的方法是维护两组已经看过的第一和第二个输入文件和一个循环:
Set<String> first = new HashSet<>();
Set<String> second = new HashSet<>();
for (HeaderAndBodyTestcase tc : tcs) {
if (! first.contains(tc.getSecondInputFile()) &&
! second.contains(tc.getFirstInputFile())) {
first.add(tc.getFirstInputFile());
second.add(tc.getSecondInputFile());
System.out.println(tc); // or add to result list
}
}
如果&#34;等于&#34;这也将有效。元素在原始列表中不会一个接一个地出现。
另请注意,在迭代相同列表时从列表中删除元素(有时工作)通常会产生意外结果。最好创建一个新的过滤列表,或者如果必须删除,请从该列表中创建Iterator
并使用它remove
方法。
仔细检查(是的,我花了很长时间才能理解你的代码),你当前工作代码中的条件实际上与我从你的问题中理解的条件大不相同,即:
考虑到这些限制,这些集合是不需要的,并且考虑到两者元素必须匹配(无论是&#39;直接&#39;还是&#39;交叉&# 39)。相反,您可以按原样使用相当多的代码,但我仍然会使用Iterator
并跟踪last
元素,并分割不同的检查以使整个代码更容易理解
HeaderAndBodyTestcase last = null;
for (Iterator<HeaderAndBodyTestcase> iter = list.iterator(); iter.hasNext();) {
HeaderAndBodyTestcase curr = iter.next();
if (curr.firstInputFile.equals(curr.secondInputFile)) {
iter.remove();
}
if (last != null) {
boolean bothEqual = curr.firstInputFile.equals(last.firstInputFile)
&& curr.secondInputFile.equals(last.secondInputFile);
boolean crossedEqual = curr.secondInputFile.equals(last.firstInputFile)
&& curr.firstInputFile.equals(last.secondInputFile);
if (bothEqual || crossedEqual) {
iter.remove();
}
}
last = curr;
}