学习完接口后,开始学习实现他们的标准类
一、ArrayList类
ArrayList类扩展AbstractList接口,并实现list接口,底层使用数组保存所有元素,分析源码:
1、底层使用数组实现
private transient Object[] elementData;
2、构造函数
public ArrayList() {
this(10);
}
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
3、存储
提供了三种方法,set,add,addall
public E set(int index, E element) {
RangeCheck(index);
E oldValue = (E) elementData[index];
elementData[index] = element;
return oldValue;
}
public boolean add(E e) {
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
}
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacity(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
4、读取get
// 返回此列表中指定位置上的元素。
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
5、删除
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue; //返回被删除值
}
public boolean remove(Object o) {
// 由于ArrayList中允许存放null,因此下面通过两种情况来分别处理。
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
// 类似remove(int index),移除列表中指定位置上的元素。
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
6、数组扩容
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
分析一下可得:
1、底层数组实现导致ArrayList查询效率高,增删效率低,由数组在内存上的存储方式决定,只需要一个偏移量就能计算出元素位置,但增删效率低是由于该过程以迭代方式进行,影响其他元素
2、数组扩容需要将旧数组复制到新数组中,有一定代价
二、LinkedList
该类实现List接口和Queue接口,链表型数据结构
public class LinkedList<E>
extends AbstractSequentialList<E> //双向链表,序列化,双向队列,clone
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
底层实现
private transient Entry<E> header = new Entry<E>(null, null, null);
private transient int size = 0;
节点类
private static class Entry<E> {
E element;
Entry<E> next;
Entry<E> previous;
Entry(E element, Entry<E> next, Entry<E> previous) {
this.element = element;
this.next = next;
this.previous = previous;
}
}
分析:
1、增删效率高,查询低
三、HashSet
该数据结构是基于hashmap实现的,其操作基本都调用底层hashmap实现,无一定顺序
四、TreeSet
底层实现,红黑树,一种基于自平衡二叉树的数据结构,看源码,Treeset底层实现一个NavigableMap接口,实现该接口的类包括treemap,treeset的底层操作基于treemap的操作