您的位置:

如何使用Java中的retainAll方法?

一、背景介绍

当我们需要比较两个Java集合时,常常需要找到它们之间的交集、并集、差集等。Java集合类提供了许多方法来帮助我们完成这些操作。其中,retainAll方法可以找到两个集合之间的交集元素并返回。

二、使用retainAll方法的几种方式

1.使用retainAll方法找到两个集合中的共同元素


List<String> list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("c");

List<String> list2 = new ArrayList<>();
list2.add("b");
list2.add("c");
list2.add("d");

list1.retainAll(list2);

System.out.println(list1); // 输出 [b, c]

以上代码中,我们创建了两个数组list1和list2。使用retainAll方法找到了它们的交集元素,并将结果保存在了list1中。

2.使用retainAll方法交集操作时的注意事项

在使用retainAll方法做交集操作时需要注意,由于retainAll方法是原地修改操作,即直接修改原来的列表,所以我们需要在保护原始数据的同时,避免修改到list1中不需要的元素。以下是如何正确使用retainAll方法的示例代码:


List<String> list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("c");

List<String> list2 = new ArrayList<>();
list2.add("b");
list2.add("c");
list2.add("d");

List<String> resultList = new ArrayList<>(list1);

resultList.retainAll(list2);

System.out.println(resultList); // 输出 [b, c]
System.out.println(list1); // 输出 [a, b, c]

我们在这个示例代码中创建了一个新的列表resultList,然后将list1的数据复制到resultList中,最后对resultList进行操作,这样就保护了list1中的原始数据,避免了出现误删。

3.使用retainAll方法找出两个集合的差集

用retainAll方法可以找到两个集合的交集,那么如何找到它们的差集呢?我们可以将它们的交集从其中一个集合中去除即可得到结果。具体实现如下:


List<String> list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("c");

List<String> list2 = new ArrayList<>();
list2.add("b");
list2.add("c");
list2.add("d");

List<String> diffList = new ArrayList<>(list1);
diffList.removeAll(list2);

System.out.println(diffList); // 输出 [a]

以上代码中,我们先将list1中的元素都复制到一个新的列表diffList中,然后使用removeAll方法从diffList中删除list2中存在的元素,最终得到它们的差集。

4.使用retainAll方法交集操作时的效率问题

当我们使用retainAll方法对两个集合做交集操作时,如果其中一个集合比另外一个集合小很多,我们可以先对其中较小的集合做一次转换,再使用retainAll方法操作。这样可以有效提高运行效率。


Set<String> set1 = new HashSet<>();
set1.add("a");
set1.add("b");
set1.add("c");

List<String> list2 = new ArrayList<>();
list2.add("b");
list2.add("c");
list2.add("d");

Set<String> set2 = new HashSet<>(list2);

if (set1.size() < set2.size()) {
    set1.retainAll(set2);
    System.out.println(set1); // 输出 [b, c]
} else {
    set2.retainAll(set1);
    System.out.println(set2); // 输出 [b, c]
}

以上代码中,我们将list2转换成了set2,对比set1和set2的大小,如果set1的大小小于set2,则对set1做retainAll操作。反之,对set2做retainAll操作。这样做可以提升运行效率。

5.使用retainAll方法比较对象

retainAll方法可以比较对象,但是要保证对象的hashCode和equals方法正确实现。


class Person {
    private int id;
    private String name;

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

List<Person> list1 = new ArrayList<>();
list1.add(new Person(1, "Tom"));
list1.add(new Person(2, "Jack"));
list1.add(new Person(3, "Lucy"));

List<Person> list2 = new ArrayList<>();
list2.add(new Person(1, "Tom"));
list2.add(new Person(2, "Jack"));
list2.add(new Person(4, "John"));

list1.retainAll(list2);

System.out.println(list1); // 输出 [Person{id=1, name='Tom'}, Person{id=2, name='Jack'}]

以上代码中,我们自定义了一个Person类,并实现了其equals和hashCode方法。我们可以通过retainAll方法,比较两个Person对象的集合。

三、总结

retainAll方法是Java集合类中非常实用的一个方法,可以帮助我们快速查找两个集合之间的交集元素,并可以用于找到两个集合的差集,同时还可以处理对象的比较。在使用retainAll方法时,我们需要注意保护好原始数据,以及处理好集合大小之间的问题,这样才能让代码更加健壮高效。