• 内功心法 -- java.util.ArrayList<E> (4)


    写在前面的话:读书破万卷,编码如有神
    --------------------------------------------------------------------
    下文主要对java.util.ArrayList<E>的4个批量操作进行介绍,主要内容包括:

    1、ArrayList的批量操作

    参考内容:

    1、JDK源码(1.7)

    -------------------------------------------------------------------- 

    1. ArrayList常用的4个批量操作                                                                                                      

    批量操作:

    (1) boolean addAll(Collection<? extends E> c)

    功能: 将子列表c中的元素全部添加到列表中去

    示例代码:

     1 public class ArrayListTest {
     2     public static void main(String[] args) {
     3         ArrayList<Integer> list = new ArrayList<Integer>();
     4         list.add(0,44);
     5         list.add(1,33);
     6         list.add(2,22);
     7         list.add(1,66);
     8         list.add(4,99);
     9         list.add(2,66);
    10         list.add(1,44);
    11         System.out.println("list :" + list);
    12         //测试ArrayList的'boolean addAll(Collection<? extends E> c)'方法的使用
    13         ArrayList<Integer> list2 = new ArrayList<Integer>();
    14         list2.add(51);
    15         list2.add(52);
    16         list2.add(53);
    17         list2.add(54);
    18         list.addAll(list2);
    19         System.out.println("list2 : " + list2);
    20         System.out.println("list :" + list);
    21     }
    22 }
    23 
    24 运行结果:
    25 list :[44, 44, 66, 66, 33, 22, 99]
    26 list2 : [51, 52, 53, 54]
    27 list :[44, 44, 66, 66, 33, 22, 99, 51, 52, 53, 54]

    源代码如下:

     1 public boolean addAll(Collection<? extends E> c) {
     2         //将子列表c转换为数组
     3         Object[] a = c.toArray();
     4         //子列表中元素的个数
     5         int numNew = a.length;
     6         //进行容量检查,如果需要扩容则进行扩容处理
     7         ensureCapacityInternal(size + numNew);  // Increments modCount
     8         //将子列表c添加到列表的size开始的位置处
     9         System.arraycopy(a, 0, elementData, size, numNew);
    10         size += numNew;
    11         return numNew != 0;
    12     }

    (2) boolean addAll(int index,Collection<? extends E> c)

    功能: 将子列表c添加到列表的index索引位置

    示例代码:

     1 public class ArrayListTest {
     2     public static void main(String[] args) {
     3         ArrayList<Integer> list = new ArrayList<Integer>();
     4         list.add(0,44);
     5         list.add(1,33);
     6         list.add(2,22);
     7         list.add(1,66);
     8         list.add(4,99);
     9         list.add(2,66);
    10         list.add(1,44);
    11         System.out.println("list :" + list);
    12         //测试ArrayList的'boolean addAll(int index,Collection<? extends E> c)'方法的使用
    13         ArrayList<Integer> list2 = new ArrayList<Integer>();
    14         list2.add(51);
    15         list2.add(52);
    16         list2.add(53);
    17         list2.add(54);
    18         System.out.println("list2 : " + list2);
    19         list.addAll(3,list2);
    20         System.out.println("list :" + list);
    21         list.addAll(30,list2);//将会抛出IndexOutOfBoundsException异常
    22         System.out.println("list :" + list);
    23     }
    24 }
    25 
    26 运行结果:
    27 list :[44, 44, 66, 66, 33, 22, 99]
    28 list2 : [51, 52, 53, 54]
    29 list :[44, 44, 66, 51, 52, 53, 54, 66, 33, 22, 99]
    30 Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 30, Size: 11
    31     at java.util.ArrayList.rangeCheckForAdd(Unknown Source)
    32     at java.util.ArrayList.addAll(Unknown Source)
    33     at ArrayListTest.main(ArrayListTest.java:24)

    源代码如下:

     1     public boolean addAll(int index, Collection<? extends E> c) {
     2         //检查index是否合法,如果不合法,则抛出异常
     3         rangeCheckForAdd(index);
     4         //将子列表转换为数组
     5         Object[] a = c.toArray();
     6         //记录子列表中元素的个数
     7         int numNew = a.length;
     8         //进行扩容检查,如果需要扩容则进行扩容处理
     9         ensureCapacityInternal(size + numNew);  // Increments modCount
    10         //计算出列表中元素需要移位的个数
    11         int numMoved = size - index;
    12         //进移位操作
    13         if (numMoved > 0)
    14             System.arraycopy(elementData, index, elementData, index + numNew,numMoved);
    15         //将子列表c放置到集合index位置开始处
    16         System.arraycopy(a, 0, elementData, index, numNew);
    17         //列表中元素个数加numNew
    18         size += numNew;
    19         return numNew != 0;
    20     } 

    (3) void clear()

    功能: 将列表中的元素清空

    示例代码:

     1 public class ArrayListTest {
     2     public static void main(String[] args) {
     3         ArrayList<Integer> list = new ArrayList<Integer>();
     4         list.add(0,44);
     5         list.add(1,33);
     6         list.add(2,22);
     7         list.add(1,66);
     8         list.add(4,99);
     9         list.add(2,66);
    10         list.add(1,44);
    11         System.out.println("list :" + list);
    12         //测试ArrayList的'void clear()'方法的使用
    13         list.clear();
    14         System.out.println("list :" + list);
    15     }
    16 }
    17 
    18 运行结果:
    19 list :[44, 44, 66, 66, 33, 22, 99]
    20 list :[]

    源代码如下:

     1     public void clear() {
     2         //fast-fail机制标识
     3         modCount++;
     4          //利用循环将列表中全部元素置为null
     5         // Let gc do its work
     6         for (int i = 0; i < size; i++)
     7             elementData[i] = null;
     8         //将属性size设置为0
     9         size = 0;
    10     }

    (4) public boolean removeAll(Collection<?> c)、public boolean retainAll(Collection<?> c)

    功能:

      removeAll(Collection<?> c)移除列表中那些也包含在指定子列表c中的所有元素

      retainAll(Collection<?> c)移除列表中那些不包含在指定子列表c中的所有元素

    示例代码: removeAll(Collection<?> c)

     1 public class ArrayListTest { 
     2     public static void main(String[] args) {
     3         ArrayList<Integer> list = new ArrayList<Integer>();
     4         list.add(22);
     5         list.add(33);
     6         list.add(44);
     7         list.add(11);
     8         list.add(15);
     9         list.add(12);
    10         list.add(7);
    11         list.add(3);
    12         System.out.println("list :" + list);
    13         //测试ArrayList的'public boolean removeAll(Collection<?> c)'方法的使用
    14         ArrayList<Integer> list2 = new ArrayList<Integer>();
    15         list2.add(44);
    16         list2.add(15);
    17         list2.add(13);
    18         System.out.println("list2 :" + list2);
    19         list.removeAll(list2);
    20         System.out.println("list.removeAll(list2) :" + list);
    21     }
    22 }
    23 
    24 运行结果:
    25 list :[22, 33, 44, 11, 15, 12, 7, 3]
    26 list2 :[44, 15, 13]
    27 list.removeAll(list2) :[22, 33, 11, 12, 7, 3]

    示例代码: retainAll(Collection<?> c) ,从运行结果可以看出运行这个方法的结果是:原列表和子列表c取交集后的结果

     1 public class ArrayListTest {
     2     public static void main(String[] args) {
     3         ArrayList<Integer> list = new ArrayList<Integer>();
     4         list.add(22);
     5         list.add(33);
     6         list.add(44);
     7         list.add(11);
     8         list.add(15);
     9         list.add(12);
    10         list.add(7);
    11         list.add(3);
    12         System.out.println("list :" + list);
    13         //测试ArrayList的'public boolean removeAll(Collection<?> c)'方法的使用
    14         ArrayList<Integer> list2 = new ArrayList<Integer>();
    15         list2.add(44);
    16         list2.add(15);
    17         list2.add(13);
    18         System.out.println("list2 :" + list2);
    19         list.retainAll(list2);
    20         System.out.println("list.retainAll(list2) :" + list);
    21     }
    22 }
    23 
    24 运行结果:
    25 list :[22, 33, 44, 11, 15, 12, 7, 3]
    26 list2 :[44, 15, 13]
    27 list.retainAll(list2) :[44, 15]

    源代码如下:(感觉JDK的源代码就是写的好呀,batchRemove()方法写的很棒)

     1 public boolean removeAll(Collection<?> c) {
     2         return batchRemove(c, false);
     3 } 
     4 
     5 public boolean retainAll(Collection<?> c) {
     6         return batchRemove(c, true);
     7 }
     8 
     9 private boolean batchRemove(Collection<?> c, boolean complement) {
    10         final Object[] elementData = this.elementData;
    11         int r = 0, w = 0;
    12         boolean modified = false;
    13         try {
    14             //利用循环查询列表元素是否在子列表c
    15             for (; r < size; r++)
    16                 if (c.contains(elementData[r]) == complement)
    17                     elementData[w++] = elementData[r];
    18         } finally {
    19             // Preserve behavioral compatibility with AbstractCollection,
    20             // even if c.contains() throws.
    21             if (r != size) {
    22                 System.arraycopy(elementData, r,
    23                                  elementData, w,
    24                                  size - r);
    25                 w += size - r;
    26             }
    27             if (w != size) {
    28                 for (int i = w; i < size; i++)
    29                     elementData[i] = null;
    30                 modCount += size - w;
    31                 size = w;
    32                 modified = true;
    33             }
    34         }
    35         return modified;
    36     }

    ---------------------------------------------------------------------------------------

    java.util.ArrayList系列文章                                                                

    java.util.ArrayList<E>(1)  java.util.ArrayList<E>(2)  java.util.ArrayList<E>(3)

    java.util.ArrayList<E>(4)  java.util.ArrayList<E>(5)  java.util.ArrayList<E>(6)

    相关知识                                                                                              

    java.util.Collection<E>   java.util.AbstractCollection<E>   java.util.List<E>

    java.util.AbstractList<E>   java.util.Iterator<E>   java.util.ListIterator<E>

    Java中的标记接口   迭代器模式   Java中的深拷贝和浅拷贝  java.util.Arrays

  • 相关阅读:
    使用xdebug调试PHP程序
    删除有序数组中的重复元素
    libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
    C++中的纯虚方法
    排序算法:堆排序算法实现及分析
    虚拟蜜罐honeyd安装使用
    软件目录结构规范(以python为例)
    python源码为何都是pass
    对类的实例直接赋值
    Path Analyzer Pro出现raw socket问题
  • 原文地址:https://www.cnblogs.com/xinhuaxuan/p/6354146.html
Copyright © 2020-2023  润新知