Java retainAll()方法的超详细讲解

 更新时间:2025年03月13日 09:38:59   作者:飞滕人生TYF  
这篇文章主要介绍了Java retainAll()方法的相关资料,retainAll()是Java集合接口中的一个方法,用于保留集合中与指定集合交集的元素,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在 Java 中,retainAll() 是 Collection 接口(ListSet 等集合类实现该接口)的一种方法,用于保留集合中与指定集合交集的元素,删除其他所有元素。

以下是对 retainAll() 方法的详细讲解。

1. 方法定义

方法签名

boolean retainAll(Collection<?> c)

参数

  • c:一个集合,用于指定要保留的元素。

返回值

  • 返回一个 boolean 值:
    • true:如果集合内容因调用此方法而改变。
    • false:如果集合内容没有改变(即调用此方法前后集合中的元素相同)。

2. 功能描述

  • retainAll() 方法会将调用该方法的集合(假设为 A)中的所有元素与参数集合(假设为 B)进行比较,保留两者交集的元素。
  • 如果 A 中的元素不在 B 中,它们会被移除。
  • 参数集合 B 不会被修改。

3. 使用示例

基本用法

import java.util.ArrayList;
import java.util.Arrays;

public class RetainAllExample {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
        ArrayList<Integer> list2 = new ArrayList<>(Arrays.asList(3, 4, 5, 6, 7));

        // 保留 list1 和 list2 的交集
        list1.retainAll(list2);

        System.out.println(list1); // 输出:[3, 4, 5]
    }
}

返回值示例

import java.util.ArrayList;
import java.util.Arrays;

public class RetainAllExample {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>(Arrays.asList("A", "B", "C"));
        ArrayList<String> list2 = new ArrayList<>(Arrays.asList("B", "C"));

        boolean isModified = list1.retainAll(list2);

        System.out.println(isModified); // 输出:true,因为 list1 发生了改变
        System.out.println(list1); // 输出:[B, C]
    }
}

4. 常见场景

场景 1:找出两个集合的交集

使用 retainAll() 可以快速找到两个集合的交集:

Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5, 6));

set1.retainAll(set2);

System.out.println(set1); // 输出:[3, 4]

场景 2:从集合中删除不需要的元素

通过与一个已知集合比较,保留需要的元素,其余元素被删除:

List<String> fruits = new ArrayList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange"));
List<String> preferredFruits = Arrays.asList("Apple", "Orange");

fruits.retainAll(preferredFruits);

System.out.println(fruits); // 输出:[Apple, Orange]

5. 注意事项和常见问题

注意事项

  • 不支持 null 集合

    • 如果参数集合为 null,调用 retainAll() 会抛出 NullPointerException
      List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
      list.retainAll(null); // 抛出 NullPointerException
      
  • 原集合会被修改

    • 调用此方法后,原集合的内容会被更改,仅保留交集元素。
  • 参数集合不可修改

    • retainAll() 不会修改参数集合。

常见问题

  • 空交集
    如果两个集合没有交集,则调用 retainAll() 后,原集合会变为空。

    List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3));
    List<Integer> list2 = new ArrayList<>(Arrays.asList(4, 5, 6));
    
    list1.retainAll(list2);
    
    System.out.println(list1); // 输出:[]
    
  • 顺序保留
    如果使用 List(如 ArrayList),retainAll() 保留交集时,元素的顺序按照原集合的顺序。

    List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
    List<Integer> list2 = new ArrayList<>(Arrays.asList(4, 3));
    
    list1.retainAll(list2);
    
    System.out.println(list1); // 输出:[3, 4]
    

6. 内部原理

执行流程

  • 遍历调用 retainAll() 的集合(如 list1)。
  • 对于每个元素,检查它是否存在于参数集合中(如 list2)。
  • 如果不存在,移除该元素。
  • 返回 true,如果至少有一个元素被移除;否则返回 false

效率

  • 取决于参数集合的类型:
    • 如果参数集合是一个 HashSetretainAll() 的性能较好,因为 HashSet 提供了快速的查找操作(O(1))。
    • 如果参数集合是一个 List,性能可能会较低,因为查找操作需要线性时间(O(n))。

7. 与其他方法的区别

removeAll()

  • 区别removeAll() 是删除当前集合中与指定集合交集的元素,而 retainAll() 是保留交集元素。
  • 示例
    List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
    List<Integer> list2 = new ArrayList<>(Arrays.asList(3, 4, 5));
    
    // removeAll 删除交集
    list1.removeAll(list2);
    System.out.println(list1); // 输出:[1, 2]
    
    // retainAll 保留交集
    list1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
    list1.retainAll(list2);
    System.out.println(list1); // 输出:[3, 4]
    

8. 总结

方法描述
作用保留集合中与指定集合交集的元素,其余元素被删除
修改原集合
参数不可为空如果参数集合为空会抛出 NullPointerException
返回值如果集合发生变化返回 true,否则返回 false
常见用途找交集、过滤集合中的元素

retainAll() 是操作集合的一个常用方法,能够帮助开发者快速进行集合间的交集操作。在使用时,需要注意原集合会被修改,因此在某些场景下可能需要备份原集合数据以避免数据丢失。

到此这篇关于Java retainAll()方法的文章就介绍到这了,更多相关Java retainAll()方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • Java object wait notify notifyAll代码解析

    Java object wait notify notifyAll代码解析

    这篇文章主要介绍了Java object wait notify notifyAll代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Spring中使用atomikos+druid实现经典分布式事务的方法

    Spring中使用atomikos+druid实现经典分布式事务的方法

    这篇文章主要介绍了Spring中使用atomikos+druid实现经典分布式事务的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-06-06
  • Java中调用SQL Server存储过程详解

    Java中调用SQL Server存储过程详解

    这篇文章主要介绍了Java中调用SQL Server存储过程详解,本文讲解了使用不带参数的存储过程、使用带有输入参数的存储过程、使用带有输出参数的存储过程、使用带有返回状态的存储过程、使用带有更新计数的存储过程等操作实例,需要的朋友可以参考下
    2015-01-01
  • Spring Security中successHandler和failureHandler使用方式

    Spring Security中successHandler和failureHandler使用方式

    这篇文章主要介绍了Spring Security中successHandler和failureHandler使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • SpringBoot中REST API 接口传参的实现

    SpringBoot中REST API 接口传参的实现

    我们在开发 REST API 的过程中,经常需要传递参数,本文主要介绍了SpringBoot中REST API 接口传参的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • Mybatis-plus3.4.3下使用lambdaQuery报错解决

    Mybatis-plus3.4.3下使用lambdaQuery报错解决

    最近在使用lambdaQuery().eq(CommonUser::getOpenId, openId).one()进行查询报错,本文主要介绍了Mybatis-plus3.4.3下使用lambdaQuery报错解决,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • Java Method类及invoke方法原理解析

    Java Method类及invoke方法原理解析

    这篇文章主要介绍了Java Method类及invoke方法原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • 在java中ArrayList集合底层的扩容原理

    在java中ArrayList集合底层的扩容原理

    这篇文章主要介绍了在java中ArrayList集合底层的扩容原理,文中有非常详细的代码示例,对正在学习java的小伙伴们有一定的帮助,需要的朋友可以参考下
    2021-04-04
  • Java实现的迷宫游戏

    Java实现的迷宫游戏

    这篇文章主要介绍了如何用Java实现一个迷宫游戏,本仓库代码是经过eclipse编译运行过的,一般情况下将本仓库代码下载下来之后,使用eclipse编译直接可以运行。
    2021-04-04
  • java 深拷贝与浅拷贝机制详解

    java 深拷贝与浅拷贝机制详解

    这篇文章主要介绍了 java 深拷贝与浅拷贝机制详解的相关资料,需要的朋友可以参考下
    2017-02-02

最新评论