在开始之前,我认为这个问题有一个非常简单的答案,我只是忽略了。我想在眼前的问题上可以更快地指出我的问题。
我有两个我要比较的ArrayLists,并从每个ArrayLists中删除重复项。第一个ArrayList
是ArrayList
旧信息,而第二个ArrayList
包含新信息。
喜欢这样
ArrayList<Person> contactList = new ArrayList();
contactList.add(new Person("Bob");
contactList.add(new Person("Jake");
contactList.add(new Person("Joe");
ontactList.add(new Person("Rob");
ArrayList<Person> updatedContactList = new ArrayList();
updatedContactList.add(new Person("Bob");
updatedContactList.add(new Person("Jake");
updatedContactList.add(new Person("Joe");
updatedContactList.add(new Person("Phil");
我的Person
类非常简单,仅为此示例创建
public class Person {
private String name;
public Person(String a_name) {
name = a_name;
}
public String getName() {
return name;
}
}
因此,使用上面的示例,我想删除所有重复项。如果可能的话,我正在尝试将它保留到两个ArrayLists中,但如果必须的话,我愿意深入克隆其中一个ArrayLists。
所以我希望生成的ArrayList
在完成比较后会在其中包含以下信息
contactList //removed Person
- Rob
updatedContactList //new Person
- Phil
以下是我放在一起的代码
for(int i = 0; i < contactList.size(); i++) {
for(int j = 0; j < updatedContactList.size(); j++) {
if(contactList.get(i).getName().equals(updatedContactList.get(j).getName())) {
//removed friends
contactList.remove(contactList.get(i));
//new friends ---- only one at a time works
//updatedContactList.remove(updatedContactList.get(j));
}
}
}
我只能从上面循环中的一个ArrayLists中删除Person,否则会得到不正确的结果。
所以我的问题是,是否有一种简单的方法可以从两个ArrayLists中删除重复的元素?如果是这样,我该怎么做呢。
我意识到我可以深度克隆更新后的ArrayList
,只是删除那个中的对象,但我想知道是否有一种方法而不必克隆它。
我也意识到我可以将所有元素填充到一个Set中,它会删除重复项,但我想将'删除'和'新'Person对象分开。
答案 0 :(得分:7)
您真正拥有的不是列表,而是集合:将旧联系人和新联系人建模为Set
。同时为equals
课程实施hashCode
和Person
,以确保正常运作。
一旦你有了这个,你就可以编写单行来计算设定差异(这就是你需要的):
final Set<Person> contactsBackup = new HashSet<>(contacts);
contacts.removeAll(updatedContacts);
updatedContacts.removeAll(contactsBackup);
请注意,这涉及再创建一个副本,但不是复制的只有深拷贝的引用。这是一个非常轻量级的操作,你不应该担心它的影响。
如果由于某些原因对我来说根本不明显,你真的需要列表,同样的代码也适合他们(List
也定义removeAll
),但你必须要活着对于O(n 2 )复杂度,此操作需要列表。
答案 1 :(得分:3)
在equals()
课程中覆盖hashCode()
和Person
,然后执行以下操作:
Set<Person> temp = new HashSet<>(contactList);
contactList.removeAll(updatedContactList);
updatedContactList.removeAll(temp);
temp.clear(); // not necessary if this code is in a method
答案 2 :(得分:2)
从Set
。
addAll
和ArrayLists
Set<Person> set = new ArrayList<Person>();
答案 3 :(得分:1)
在这种情况下,使用Set而不是List(如果可能的话,如果你使用说Hibernate从DB获取数据,则使用它)。然后,您可以在person类中覆盖equals和hashcode方法,以便在添加所需的比较时可以进行并且可以取出重复项。可以使用LinkedHashSet,因为随着数据的增长,列表会变慢。
答案 4 :(得分:0)
这是一个利用Java 8功能的一线优雅解决方案
public static final <T> void removeCommonEntries(Collection<T> a, Collection<T> b){
b.removeIf(i -> a.remove(i));
}
我将此解决方案放入您的自定义CollectionUtils
。