内功心法 -- 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

posted @ 2017-02-07 21:02  火爆泡菜  阅读(390)  评论(0编辑  收藏  举报