一、JDK中ArrayList是如何实现的
1、先看下ArrayList从上而下的层次图:
说明:
从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList、List、Collection等上层的接口所设定的,而ArrayList实现或继承了上层的规则,然后重新或扩展来处理集合中的数据。
2、看看接口:Iterable<E>中都定义了那些规则?
JDK1.8中的源码:
1 package java.lang; 2 3 import java.util.Iterator; 4 import java.util.Objects; 5 import java.util.Spliterator; 6 import java.util.Spliterators; 7 import java.util.function.Consumer; 8 public interface Iterable<T> {//实现这个接口允许对象成为 "foreach" 语句的目标。 9 Iterator<T> iterator(); 10 default void forEach(Consumer<? super T> action) { 11 Objects.requireNonNull(action); 12 for (T t : this) { 13 action.accept(t); 14 } 15 } 16 default Spliterator<T> spliterator() { 17 return Spliterators.spliteratorUnknownSize(iterator(), 0); 18 } 19 }
这里说明一下:
(1)Consumer<? super T> action 可以理解为:实现了Consumer接口的实现类对象。
(2)accept(T t) T 是每一次forEach方法处理的数据类型,t是数据
(3)spliterator():Spliterator(splitable iterator可分割迭代器)接口是Java为了并行遍历数据源中的元素而设计的迭代器。也就是收JDK1.8版本已经支持多核并发处理集合中的数据了,你只需要告诉JDK你要做什么并行任务,关注业务本身,至于如何并行,怎么并行效率最高,就交给JDK自己去思考和优化速度了。
简单举个forEach的例子:
1 package com.xfwl.test; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.function.Consumer; 6 @SuppressWarnings("unchecked") 7 public class Test2 { 8 public static void main(String[] args) { 9 List alist=new ArrayList(); 10 alist.add("1"); 11 alist.forEach(new T()); 12 } 13 /** 14 * Consumer接口测试实现类T 15 * @param <E> 16 */ 17 static class T implements Consumer{ 18 public T(){} 19 public void accept(Object e) { 20 System.out.println("当前数据:"+e); 21 } 22 public Consumer andThen(Consumer after) { 23 // TODO Auto-generated method stub 24 return null; 25 } 26 } 27 }
运行结果:
当前数据:1
总结一下:
(1)接口Iterable,定义了遍历集合中的数据的方法:forEach(),这个方法需要一个实现了Consumer接口的参数;
(2)接口Iterable,定义了一个可以实现并发的迭代器,具体如何实现和优化交给jdk自己处理,我们只负责使用集合即可。
3、看看接口:Collection<E>中定义了那些规则?
JDK1.8中的源码:
1 package java.util; 2 import java.util.function.Predicate; 3 import java.util.stream.Stream; 4 import java.util.stream.StreamSupport; 5 6 public interface Collection<E> extends Iterable<E> { 7 int size(); //获取集合元素总数 8 boolean isEmpty(); //判断集合是否非空 9 boolean contains(Object o); //判断集合是否包含指定元素 10 Iterator<E> iterator(); //获取迭代器 11 Object[] toArray(); //把集合转化成Object类型数组对象 12 <T> T[] toArray(T[] a); //把集合转化成指定T类型数组对象 13 boolean add(E e); //添加数据到集合 14 boolean remove(Object o); //从集合中移除数据 15 boolean containsAll(Collection<?> c); //集合是否包含另一个集合 16 boolean addAll(Collection<? extends E> c); //集合添加另外一个集合 17 boolean removeAll(Collection<?> c); //集合中移除另外一个集合中的内容 18 default boolean removeIf(Predicate<? super E> filter) {//JDK1.8开始加入的方法,按指定条件移除集合中的信息 19 Objects.requireNonNull(filter); 20 boolean removed = false; 21 final Iterator<E> each = iterator(); 22 while (each.hasNext()) { 23 if (filter.test(each.next())) { 24 each.remove(); 25 removed = true; 26 } 27 } 28 return removed; 29 } 30 boolean retainAll(Collection<?> c); //移除此 collection 中未包含在指定 collection 中的所有元素 31 void clear(); //清除集合中的信息 32 boolean equals(Object o); //比较此 collection 与指定对象是否相等。 33 int hashCode(); //返回此 collection 的哈希码值。 34 @Override 35 default Spliterator<E> spliterator() { //JDK1.8开始新加入的方法,返回当前集合的并发迭代器 36 return Spliterators.spliterator(this, 0); 37 } 38 default Stream<E> stream() { //JDK1.8开始新加入的方法,通过传入并发迭代器,来使用stream过滤集合数据 39 return StreamSupport.stream(spliterator(), false);//返回的流是顺序的 40 } 41 default Stream<E> parallelStream() { //JDK1.8开始新加入的方法,通过传入并发迭代器,来使用stream过滤集合数据 42 return StreamSupport.stream(spliterator(), true);//返回的流是并行的 43 } 44 }
这里说明一下:
(1)JDK8版本中,接口中可以定义方法的实现了,即方法可以定义方法体了。
(2)Collection中定义了一些针对集合数据的添加,删除,判空,是否存在,整块集合的包含+移除等操作,以及JDK1.8开始新增的方法:removeIf()和spliterator(),stream()以及parallelStream()方法。
简单举个stream()的例子:
1 package com.xfwl.test; 2 3 import java.util.Arrays; 4 import java.util.List; 5 import java.util.function.Consumer; 6 import java.util.stream.Collectors; 7 @SuppressWarnings("unchecked") 8 public class Test2 { 9 public static void main(String[] args) { 10 List<Integer> alist=Arrays.asList(1,2,3,4,5,6,7,8,9,10); 11 alist=alist.stream().filter(s -> (s>5)).collect(Collectors.toList());//lumbda表达式
12 for(int i:alist){ 13 System.out.println(i); 14 } 15 16 } 17 }
运行结果:
6
7
8
9
10
继续修改代码,举个removeIf()的例子:
1 package com.xfwl.test; 2 3 import java.util.Arrays; 4 import java.util.List; 5 import java.util.function.Consumer; 6 import java.util.stream.Collectors; 7 @SuppressWarnings("unchecked") 8 public class Test2 { 9 public static void main(String[] args) { 10 List<Integer> alist=Arrays.asList(1,2,3,4,5,6,7,8,9,10); 11 alist=alist.stream().filter(s -> (s>5)).collect(Collectors.toList());//lumbda表达式 12 alist.removeIf(s->s==10); 13 for(int i:alist){ 14 System.out.println(i); 15 } 16 } 17 }
运行结果:
6
7
8
9
4、看看抽象类:AbstractCollection<E>中定义了那些规则?
JDK1.8中的源码
1 package java.util; 2 public abstract class AbstractCollection<E> implements Collection<E> { 3 protected AbstractCollection() { 4 } 5 public abstract Iterator<E> iterator(); 6 7 public abstract int size(); 8 9 public boolean isEmpty() { 10 return size() == 0; 11 } 12 public boolean contains(Object o) { 13 Iterator<E> it = iterator(); 14 if (o==null) { 15 while (it.hasNext()) 16 if (it.next()==null) 17 return true; 18 } else { 19 while (it.hasNext()) 20 if (o.equals(it.next())) 21 return true; 22 } 23 return false; 24 } 25 public Object[] toArray() { 26 // Estimate size of array; be prepared to see more or fewer elements 27 Object[] r = new Object[size()]; 28 Iterator<E> it = iterator(); 29 for (int i = 0; i < r.length; i++) { 30 if (! it.hasNext()) // fewer elements than expected 31 return Arrays.copyOf(r, i); 32 r[i] = it.next(); 33 } 34 return it.hasNext() ? finishToArray(r, it) : r; 35 } 36 @SuppressWarnings("unchecked") 37 public <T> T[] toArray(T[] a) { 38 // Estimate size of array; be prepared to see more or fewer elements 39 int size = size(); 40 T[] r = a.length >= size ? a : 41 (T[])java.lang.reflect.Array 42 .newInstance(a.getClass().getComponentType(), size); 43 Iterator<E> it = iterator(); 44 45 for (int i = 0; i < r.length; i++) { 46 if (! it.hasNext()) { // fewer elements than expected 47 if (a == r) { 48 r[i] = null; // null-terminate 49 } else if (a.length < i) { 50 return Arrays.copyOf(r, i); 51 } else { 52 System.arraycopy(r, 0, a, 0, i); 53 if (a.length > i) { 54 a[i] = null; 55 } 56 } 57 return a; 58 } 59 r[i] = (T)it.next(); 60 } 61 // more elements than expected 62 return it.hasNext() ? finishToArray(r, it) : r; 63 } 64 65 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 66 @SuppressWarnings("unchecked") 67 private static <T> T[] finishToArray(T[] r, Iterator<?> it) { 68 int i = r.length; 69 while (it.hasNext()) { 70 int cap = r.length; 71 if (i == cap) { 72 int newCap = cap + (cap >> 1) + 1; 73 // overflow-conscious code 74 if (newCap - MAX_ARRAY_SIZE > 0) 75 newCap = hugeCapacity(cap + 1); 76 r = Arrays.copyOf(r, newCap); 77 } 78 r[i++] = (T)it.next(); 79 } 80 // trim if overallocated 81 return (i == r.length) ? r : Arrays.copyOf(r, i); 82 } 83 84 private static int hugeCapacity(int minCapacity) { 85 if (minCapacity < 0) // overflow 86 throw new OutOfMemoryError 87 ("Required array size too large"); 88 return (minCapacity > MAX_ARRAY_SIZE) ? 89 Integer.MAX_VALUE : 90 MAX_ARRAY_SIZE; 91 } 92 public boolean add(E e) { 93 throw new UnsupportedOperationException(); 94 } 95 public boolean remove(Object o) { 96 Iterator<E> it = iterator(); 97 if (o==null) { 98 while (it.hasNext()) { 99 if (it.next()==null) { 100 it.remove(); 101 return true; 102 } 103 } 104 } else { 105 while (it.hasNext()) { 106 if (o.equals(it.next())) { 107 it.remove(); 108 return true; 109 } 110 } 111 } 112 return false; 113 } 114 public boolean containsAll(Collection<?> c) { 115 for (Object e : c) 116 if (!contains(e)) 117 return false; 118 return true; 119 } 120 public boolean addAll(Collection<? extends E> c) { 121 boolean modified = false; 122 for (E e : c) 123 if (add(e)) 124 modified = true; 125 return modified; 126 } 127 public boolean removeAll(Collection<?> c) { 128 Objects.requireNonNull(c); 129 boolean modified = false; 130 Iterator<?> it = iterator(); 131 while (it.hasNext()) { 132 if (c.contains(it.next())) { 133 it.remove(); 134 modified = true; 135 } 136 } 137 return modified; 138 } 139 public boolean retainAll(Collection<?> c) { 140 Objects.requireNonNull(c); 141 boolean modified = false; 142 Iterator<E> it = iterator(); 143 while (it.hasNext()) { 144 if (!c.contains(it.next())) { 145 it.remove(); 146 modified = true; 147 } 148 } 149 return modified; 150 } 151 public void clear() { 152 Iterator<E> it = iterator(); 153 while (it.hasNext()) { 154 it.next(); 155 it.remove(); 156 } 157 } 158 public String toString() { 159 Iterator<E> it = iterator(); 160 if (! it.hasNext()) 161 return "[]"; 162 163 StringBuilder sb = new StringBuilder(); 164 sb.append('['); 165 for (;;) { 166 E e = it.next(); 167 sb.append(e == this ? "(this Collection)" : e); 168 if (! it.hasNext()) 169 return sb.append(']').toString(); 170 sb.append(',').append(' '); 171 } 172 } 173 174 }