简体   繁体   English

Java ArrayList从两个列表中删除重复项

[英]Java ArrayList remove duplicates from both the lists

I have 2 ArrayList of custom objects. 我有2个自定义对象的ArrayList。 I want to remove duplicate entries from both the ArrayList. 我想从ArrayList中删除重复的条目。

The objects have three fields: fName, lName, and id. 对象有三个字段:fName,lName和id。 If the id occurs multiple times, I want to remove from both the lists. 如果id多次出现,我想从两个列表中删除。

How can I do that? 我怎样才能做到这一点?

I am fine with merging both the lists and removing the 2 duplicate entries as well. 我很好地合并了两个列表并删除了2个重复的条目。

If you want to merge: simply copy the content of both lists to a map. 如果要合并:只需将两个列表的内容复制到地图即可。 Then you don't have the duplicates anymore (but you loose your actual ordering): 那你就不再有重复了(但是你的实际排序却没有了):

Map<Integer, MyObject> temp = new HashMap<Integer, MyObject>();
for (MyObject obj:firstList) {
   temp.put(obj.getId(), obj);
}
for (MyObject obj:secondList) {
   temp.put(obj.getId(), obj);
}
List<MyObject> result = new ArrayList<MyObject>(temp.values());

If your classes have a correct implementation of the equals and hashCode method, turn the list into a HashSet to eliminate the duplicates. 如果您的类具有equalshashCode方法的正确实现,请将列表转换为HashSet以消除重复项。 The HashSet<T> constructor accepts a Collection<T> so you should be good to go. HashSet<T>构造函数接受Collection<T>所以你应该好好去。

If you need some custom comparator function (like the one in your case which compares only id ), pass in a custom Comparator<T> implementation when creating the TreeSet . 如果您需要一些自定义比较器函数(如您的情况下只比较id ),请在创建TreeSet时传入自定义Comparator<T>实现。 To sum it up, just create a comparator which compares id s of both the objects and pass it to the TreeSet constructor. 总结一下,只需创建一个比较器,比较两个对象的id并将其传递给TreeSet构造函数。 Then adding items from both the lists to this set will take care of eliminating the duplicates. 然后将两个列表中的项目添加到此集合将负责消除重复项。 Something like: 就像是:

public class Test {

    public static void main(String[] args) {
        Person p1 = new Person("first", "id1");
        Person p2 = new Person("dummy", "id1"); // same id as above
        Person p3 = new Person("second", "id2");
        Person p4 = new Person("third", "id1");
        List<Person> asList = Arrays.asList(p1, p2, p3, p4);
        CustomComparator comparator = new CustomComparator();
        TreeSet<Person> ts = new TreeSet<Person>(comparator);
        TreeSet<Person> duplicates = new TreeSet<Person>(comparator);
        for (Person p : asList) {
            if (ts.contains(p) || duplicates.contains(p)) {
                duplicates.add(p);
                ts.remove(p);
            } else {
                ts.add(p);
            }
        }
        System.out.println(ts);
    }

}

class Person {

    public Person(String name, String id) {
        super();
        this.name = name;
        this.id = id;
    }

    public String name;

    public String id;

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Person [id=");
        builder.append(id);
        builder.append(", name=");
        builder.append(name);
        builder.append("]");
        return builder.toString();
    }

}

class CustomComparator implements Comparator<Person> {

    @Override
    public int compare(Person o1, Person o2) {
        return o1.id.compareTo(o2.id);
    }

}

Use Set for this purpose. 使用Set为此目的。

Note: Great care must be exercised if mutable objects are used as set elements. 注意:如果将可变对象用作set元素,则必须非常小心。 The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. 如果在对象是集合中的元素的同时以影响等于比较的方式更改对象的值,则不指定集合的​​行为。 A special case of this prohibition is that it is not permissible for a set to contain itself as an element. 这种禁令的一个特例是,不允许集合将自身作为一个要素包含在内。

HashSet<Integer> list_1_ids = new HashSet<Integer>();
HashSet<Integer> list_2_ids = new HashSet<Integer>();
for (CustomObject x : list1) list_1_ids.add(x.id);
for (CustomObject x : list2) list_2_ids.add(x.id);
HashSet<Integer> both_ids = list_1_ids;
both_ids.retainAll(list_2_ids);
List<CustomObject> pruned_list_1 = new ArrayList<CustomObject>();
for (CustomObject x : list1) if (!both_ids.contains(x.id)) pruned_list_1.add(x);
List<CustomObject> pruned_list_2 = new ArrayList<CustomObject>();
for (CustomObject x : list2) if (!both_ids.contains(x.id)) pruned_list_2.add(x);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM