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方法的介绍和分析到此结束,文中难免有不足之处,望大家指正交流。

瞬间教你学会使用java中list的retainAll方法的更多相关文章

  1. java中substring的使用方法

    java中substring的使用方法 str=str.substring(int beginIndex);截取掉str从首字母起长度为beginIndex的字符串,将剩余字符串赋值给str: str ...

  2. Java中Set的contains()方法

    Java中Set的contains()方法 -- hashCode与equals方法的约定及重写原则 翻译人员: 铁锚 翻译时间: 2013年11月5日 原文链接: Java hashCode() a ...

  3. [java,2017-05-16] java中清空StringBuffer的方法以及耗费时间比较

    java中清空StringBuffer的方法,我能想到的有4种: 1. buffer.setLength(0);  设置长度为0 2. buffer.delete(0, buffer.length() ...

  4. java中BorderLayout的使用方法

    相关设置: 使用BorderLayout布局上下左右中布局5个按键,单击中间的那个按键时就关闭窗口 代码: /**** *java中BorderLayout的使用方法 * 使用BorderLayout ...

  5. 【Java】Java中常用的String方法

    本文转载于:java中常用的String方法 1 length()字符串的长度 String a = "Hello Word!"; System.out.println(a.len ...

  6. Java中Set的contains()方法——hashCode与equals方法的约定及重写原则

    转自:http://blog.csdn.net/renfufei/article/details/14163329 翻译人员: 铁锚 翻译时间: 2013年11月5日 原文链接: Java hashC ...

  7. java中equals和hashCode方法随笔二

    前几天看了篇关于java中equals和hashCode方法的解析 1.Object类中的equals方法和hashCode方法. Object类中的equals和hashCode方法简单明了,所有的 ...

  8. java中static变量和方法的总结

    转自:http://blog.csdn.net/haobo920/article/details/5921621 java中static变量和方法的总结 java中一切皆是对象 一个类中对象的定义一般 ...

  9. Java中wait和sleep方法的区别

    1.两者的区别 这两个方法来自不同的类分别是Thread和Object 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁). wait ...

随机推荐

  1. [源码分析] 带你梳理 Flink SQL / Table API内部执行流程

    [源码分析] 带你梳理 Flink SQL / Table API内部执行流程 目录 [源码分析] 带你梳理 Flink SQL / Table API内部执行流程 0x00 摘要 0x01 Apac ...

  2. EF-三种映射

    更改实体的类名称,字段名称,来映射表名称,表字段.  1,用EF自带的特性方式: 直接加上特性,更新对应的类名,字段名以及引用类,字段名的相关地方  2,参考NHibernate建立一个EF自带的映射 ...

  3. nodejs之https双向认证

    说在前面 之前我们总结了https的相关知识,如果不懂可以看我另一篇文章:白话理解https 有关证书生成可以参考:自签证书生成 正题 今天使用nodejs来实现https双向认证 话不多说,直接进入 ...

  4. PHP $_FILES的应用

    关于文件上传这块,如果处理不好的话,很容易成为黑客入侵的开口,例如黑客在你这个上传接口里放一段木马的文件,那只能祝你好运了. 所以,我们上传文件的时候都会先判断, 但是一般的操作是先上传,再判断,如果 ...

  5. 不论是 Basic Auth 还是 Digest Auth,都会有 Authorization 字段

    GET /dir/index.html HTTP/1.0 Host: localhost Authorization: Digest username="Mufasa", real ...

  6. Python 如何写 Ubuntu syslog

    address='/dev/log' 是关键 import logging from logging.handlers import SysLogHandler logger = logging.ge ...

  7. 异常:由 spring-session pom 引发

    错误异常 Correct the classpath of your application so that it contains a single, compatible version of o ...

  8. (转)如何学好C++语言

    原文:http://coolshell.cn/articles/4119.html   作者:陈皓 昨天写了一篇如何学好C语言,就有人回复问我如何学好C++,所以,我把我个人的一些学习经验写在这里,希 ...

  9. Linux Centos7(Mac)安装Docker

    docker 强调隔离性 docker:官网 docker:镜像官网:        镜像官网可以所有应用,选择安装环境:会给出安装命令,例如:docker pull redis 默认拉取最新的版本( ...

  10. SpringBoot系列(十二)过滤器配置详解

    SpringBoot(十二)过滤器详解 往期精彩推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件 ...