如何根据对象属性删除两个列表共有的内容。下面我试图从testList2中删除包含与testList1相同的str1参数的所有值。
我认为我可以覆盖正在比较的类中的equals方法,因为在使用removeAll时使用了equals方法?
testList1& testList2的类型为ArrayList,并且都包含Test对象列表。
testList1.removeAll(testList2);
public class Test{
private String str1;
private String str2;
public Test(String str1 , String str2){
this.str1 = str1;
this.str2 = str2;
}
public String getStr1() {
return str1;
}
public String getStr2() {
return str2;
}
public boolean equals(Object o){
Test t = (Test)o;
return this.getStr1().equalsIgnoreCase(t.getStr2());
}
}
答案 0 :(得分:1)
如果您希望两个列表中的所有对象都没有重复(至少这是我在编辑之前所理解的):
Set<Test> both = new HashSet<Test>();
both.addAll(testList1);
both.addAll(testList2);
//and if you really need to use a List instead of a Set
List<Test> result = new ArrayList<Test>(both);
当然,您仍然必须覆盖equals()
,以便收藏品能够理解您的意思。
答案 1 :(得分:1)
是的,覆盖equals(...)
应该与removeAll(...)
一起使用,因为ArrayList
将使用它进行相等性检查。
在幕后,removeAll(...)
中的AbstractCollection
方法(ArrayList
的超类)会在传递给{{1}的集合上调用contains(entry)
}}。 removeAll(...)
中的contains(...)
将使用ArrayList
获取元素的索引,indexOf(...)
依次循环遍历所有元素,并在其上调用equals(...)
。
也就是说,很明显使用列表的removeAll()
实现具有O(n 2 )复杂度(循环遍历源列表以及通过参数列表的每个条目循环)更大的列表可能会变慢。
因此,您可能希望将要删除的一组对象传递给removeAll(...)
。这将导致O(n * log(n))复杂度(源列表上的循环保持不变,但对集合的contains
调用仅为O(log(n))。
答案 2 :(得分:1)
首先equals()
应确定两个对象逻辑上是否相等。如果这些对象在str1
字段相等时在逻辑上相等,那么您可以使用equals并使用为集合定义的方法。在这种情况下,equals()
契约(在java.lang.Object中定义)值得一读。
如果我正在使用您的代码,我宁愿您使用迭代解决问题而不是定义不正确的equals()
方法(警告:未经过测试的代码):
Set<String> strings = new HashSet<String>(listOne.size());
for(Test t : listOne){
strings.add(t.getStr1());
}
Iterator<Test> it = listTwo.iterator();
while(it.hasNext()){
Test t = it.next();
if(strings.contains(t.getStr1())
it.remove();
}
答案 3 :(得分:0)
我认为我可以覆盖正在比较的类中的equals方法,因为在使用removeAll时使用了equals方法?
// you need to compare the current values to the values in t
public boolean equals(Object o){
Test t = (Test)o;
return t.getStr1().equalsIgnoreCase(t.getStr1())
&& t.getStr2().equalsIgnoreCase(t.getStr2());
}
如果可以的话,我也会将这些字段作为最终字段。
答案 4 :(得分:0)
如果test1中存在str1&amp; testList2,你想要从两个列表中删除它,对吧!
// Iterate till all elements
for (int i=0; i < testList.size()-1; i++) {
Test t1 = testList1.get(i); // Get element i of TestList1 Arr
Test t2 = testList2.get(i); // Get element i of TestList2 Arr
// If t1 & t2 both contains same values in str1 & str2
if (t1.equuals(str1) && t2.equals(str1) ) {
// Remove the elements from list
testList1.remove(i);
testlist2.remove(i);
}
}
如果要在Test对象中重写equals
// This will comapre current instance and the passed instance
public boolean equals(String toCompare, Test obj) {
return (this.equals(toComare) && obj.equals(toComapre));
}
希望这会对你有所帮助。使用任何方便你的方法都可以。