retainAll方法简介

当我们有两个list集合的时候,我们可以使用retainAll方法求得两个list集合的子集。retainAll是Collection接口中提供的一个方法,各个实现类有自己的实现方式,我们这里介绍ArrayList的实现方式。

retainAll源码深入

可以看到collection接口中的retainAll方法,需要传入一个集合。

boolean retainAll(Collection<?> c);

进入arrayList的方法实现。可以看到如下代码:

    public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}

由以上代码可知,传入的集合不能为null。接下来看看batchRemove方法。

    private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}

我们看到上述方法的流程如下:

首先获得当前对象的所有元素,然后通过r和w变量标记两个集合公共元素的个数。初始化标志位为false。然后进入循环遍历当前集合,如果传入的集合中包含当前集合的元素,就直接将这个元素保存下来。最后到finally块中,如果r不等于size,证明在循环的过程中出现了异常,然后将剩余的元素进行复制,重新计算数组的剩余元素值。如果剩余的元素值不等于size,则将多余的位置进行清空。更改modcount的值。这个modcount是父类abstarctlist的值,初始值为0,集合中的内容没修改一次则增加1。最后重新设置size的大小。返回是否修改值。

retainAll返回值的说明

这里有两个说明。

第一个:如果集合A数组的大小没有改变,则返回false。如果集合A和集合B是完全相同的集合,也会返回false。

public static void main(String[] args) {
ArrayList<String> list1= new ArrayList<String>();
list1.add("123");
ArrayList<String> list2= new ArrayList<String>();
list2.add("123");
System.out.println(list1.retainAll(list2));
}

如上代码会返回false。

第二个:两个集合没有交集,会返回true。

public static void main(String[] args) {
ArrayList<String> list1= new ArrayList<String>();
list1.add("123");
ArrayList<String> list2= new ArrayList<String>();
list2.add("12345");
System.out.println(list1.retainAll(list2));
}

如上代码会返回true。

总结:当集合A的大小改变的时候返回的是True,大小没有改变的时候返回的是False。

retainAll的判断方法

public static void main(String[] args) {
ArrayList<String> list1= new ArrayList<String>();
list1.add("123");
ArrayList<String> list2= new ArrayList<String>();
list2.add("123");
list1.retainAll(list2);
if(list1.size()>0){
System.out.println("有交集");
}else{
System.out.println("没有交集");
}
}

通过判断集合的大小,来确定是否存在交集。不能通过方法返回的True和False来判断。

retainAll的实际效果使用

我们声明两个集合,通过调用retainAll,保留两个集合的交集。最后再看输出的效果。

    public static void main(String[] args) {
Collection collection1 = new ArrayList();
collection1.add("a");
collection1.add("b");
collection1.add("c");
Collection collection2 = new ArrayList();
collection2.add("ab");
collection2.add("abc");
collection2.add('a');
System.out.println(collection1);
boolean flag = collection1.retainAll(collection2);
System.out.println(flag);
System.out.println(collection1);
}

执行结果如下:

[a, b, c]
true
[a]

保留了两个结合的交集。

总结

list的retainAll方法的介绍和分析到此结束,文中难免有不足之处,望大家指正交流。

最新文章

  1. 利用AE编写切图工具的一些探讨
  2. Node.js ORM 框架 sequelize 实践
  3. Linux下的网络远程安装
  4. c# JD快速搜索工具,2015分析JD搜索报文,模拟请求搜索数据,快速定位宝贝排行位置。
  5. Maven解决Missing artifact com.sun:tools:jar:1.5.0错误
  6. python使用VBA:Excel创建图表(转)
  7. ViewPage 大圣归来 原生示例
  8. ZooKeeper 的安装和配置---单机和集群
  9. 1.4. 为现有的应用程序添加 Core Data 支持(Core Data 应用程序实践指南)
  10. 【重磅】微软开源自动机器学习工具 - NNI
  11. maven如何单独启动插件目标
  12. 文件处理,三元操作符,seek()函数,迭代函数和列表解析,reduce函数
  13. mysql主从复制-读写分离-原理
  14. css points
  15. openresty--centos7下开发环境安装
  16. 常用jar命令
  17. js 代码风格(2)
  18. Redis面向java的Client
  19. 51nod 最大M子段和系列
  20. 具体解释Android定位

热门文章

  1. windows搭建Selenium
  2. 排序1 - 选择排序 &amp; 插入排序
  3. 使用binlog2sql工具来恢复数据库
  4. python爬取优美图库海量图片,附加代码,一键爬取
  5. 一篇文章掌握网页解析神器——xpath
  6. php表格--大数据处理
  7. thinkphp5 -- _initialize()初始化控制器
  8. js点击事件,数字累加
  9. [20170616]recover copy of datafile 6.txt
  10. 【20180129】java进程经常OOM,扩容swap。