一、含义
1、removeAll方法 从list中删除指定集合中包含的所有元素
2、retainAll方法 从list中删除指定集合中不包含的所有元素
二、源码:
1、removeAll源码
- public boolean removeAll(Collection> c) {
- Objects.requireNonNull(c);//判断参数是否为空
- return batchRemove(c, false);//删除指定集合中包含的所有元素
- }
2、retainAll源码
- public boolean retainAll(Collection> c) {
- Objects.requireNonNull(c);//判断参数是否为空
- return batchRemove(c, true);//删除指定集合中不包含的所有元素
- }
判断参数是否为空的方法暂不考虑,两个方法都调用了batchRemove方法,只是第二个参数传递不同,一个是false一个是true
3、batchRemove源码
- //用removeAll方法说明(complement = false)
- private boolean batchRemove(Collection> c, boolean complement) {
- //elementData是arraylist中存储数据的数组
- final Object[] elementData = this.elementData;
- //r控制循环、w控制elementData的下表
- int r = 0, w = 0;
- boolean modified = false;
- try {
- //举例说明for循环
- //原数组elementData中的数据["a","b","c","d","e"]
- //参数的Collection假设为arraylist,数组是["b","c","d"]
- //for循环第一轮 r=0,w=0判读语句(c.contains(elementData[r]) == complement)为true
- //进入if的代码块 elementData[w++] = elementData[r];
- //也就是elementData[0] = elementData[0] 即elementData[0]=a; w自增
- //for循环第二轮 r=1,w=1判读语句(c.contains(elementData[r]) == complement)为false
- //for循环第三轮 r=2,w=1判读语句(c.contains(elementData[r]) == complement)为false
- //for循环第四轮 r=3,w=1判读语句(c.contains(elementData[r]) == complement)为false
- //for循环第五轮 r=4,w=1判读语句(c.contains(elementData[r]) == complement)为true
- //进入if的代码块 elementData[w++] = elementData[r];
- //也就是elementData[1] = elementData[4] 即elementData[1]=e; w自增
- //循环完成后elementData中的数据["a","e","c","d","e"](注意第二个元素) r=5 w=2
- for (; r < size; r++)
- if (c.contains(elementData[r]) == complement)
- elementData[w++] = elementData[r];
- } finally {
- //如果contains方法使用过程报异常,将剩下的元素都赋值给集合elementData
- if (r != size) {
- System.arraycopy(elementData, r, elementData, w, size - r);
- w += size - r;
- }
- //将elementData[w]之后的数据置空
- if (w != size) {
- for (int i = w; i < size; i++)
- elementData[i] = null;
- modCount += size - w;
- size = w;
- modified = true;
- }
- //完成后elementData中的数据["a","e",null,null,null]
- }
- return modified;
- }
4、在batchRemove方法中的判断语句if (c.contains(elementData[r]) == complement)中的contains方法
- //以arraylist为例
- public boolean contains(Object o) {
- //调用了indexOf方法
- return indexOf(o) >= 0;
- }
5、在contains方法中调用了indexOf方法
- //以arraylist为例
- public int indexOf(Object o) {
- //null的情况暂不考虑
- if (o == null) {
- for (int i = 0; i < size; i++)
- if (elementData[i]==null)
- return i;
- } else {
- //循环调用,利用equals方法判断是否存在
- for (int i = 0; i < size; i++)
- if (o.equals(elementData[i]))
- return i;
- }
- return -1;
- }
三、总结
1、removeAll或者retainAll方法调用private方法batchRemove。
2、batchRemove方法中有个判断语句调用了contains方法。
3、contains方法中调用了indexOf方法。
4、indexOf方法中调用equals方法。
- ArrayList
list1 = new ArrayList(); - list1.add("a");
- list1.add("b");
- list1.add("c");
- list1.add("d");
- list1.add("e");
-
- ArrayList
list2 = new ArrayList(); - list2.add("b");
- list2.add("c");
- list2.add("d");
-
- list1.removeAll(list2);
-
- for(String s : list1) {
- System.out.println(s);
- }
上面的代码段可以得到预期的效果 输出 a e
- ArrayList
personList1 = new ArrayList(); - ArrayList
personList2 = new ArrayList(); -
- Person persona = new Person("a", 18);
- Person personb = new Person("b", 19);
- Person personc = new Person("c", 20);
- Person persond = new Person("d", 21);
- Person persone = new Person("e", 22);
-
- Person personf = new Person("b", 19);
- Person persong = new Person("c", 20);
- Person personh = new Person("d", 21);
-
- personList1.add(persona);
- personList1.add(personb);
- personList1.add(personc);
- personList1.add(persond);
- personList1.add(persone);
-
- personList2.add(personf);
- personList2.add(persong);
- personList2.add(personh);
-
- personList1.removeAll(personList2);
-
-
- for(Person p : personList1) {
- System.out.println(p.getName());
- }
上面的代码段如果要用personList1.removeAll(personList2);得到预期的效果需要重写Person类的equals方法
- public class Person {
-
- private String name;
- private int age;
-
- public Person() {
- super();
- }
-
- public Person(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
- //重写equals方法后 arraylist的removeAll方法能够得到预期的效果
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof Person) {
- Person p = (Person) obj;
- if (this.name.equals(p.getName()) && this.age == p.getAge()) {
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
-
- }