List中常用的2个子类,ArrayList擅长随机访问,但是添加或移除元素较慢和LinkedList代价较低的增加和删除,优化了顺序访问。在随机访问相对比较慢,特性较ArrayList多
List接口方法:
int size();返回元素个数
ArrayList,LinkedList
public int size() {
return size;//返回实时记录添加或者减少元素的个数,此属性设计为私有方法,是不能随意更改的
}
boolean isEmpty();是否为空
ArrayList,LinkedList
public boolean isEmpty() {
return size == 0;//重写了AbstractCollection的isEmpty方法,其实现为size()==0;LinkedList则没有重写
}
int indexOf(Object o);//返回下标,要重写equels方法
ArrayList
public int indexOf(Object o) {
if (o == null) { //根据源码传入空也能查出下标,防止空指针,对空做特殊处理查找
for (int i = 0; i < size; i++) //因为elementData的长度比size大,size才是真正的长度
if (elementData[i]==null) //返回第一个为空的
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i])) //Object最好重写equles方法
return i;
}
return -1;
}
public int indexOf(Object o) {
int index = 0;
if (o==null) {
for (Entry e = header.next; e != header; e = e.next) { //header是LinkedList的头部,头部的下一个开始循环
if (e.element==null) //如果为空返回第几个,index是局部变量记录的
return index;
index++;
}
} else {
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
}
return -1;
}
E get(int index);得到第几个
ArrayList
public E get(int index) {
RangeCheck(index);//index是否大于size
return (E) elementData[index];根据数组下标得到第几个
}
LinkedList
private Entry<E> entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+ //检查是否超出个数
", Size: "+size);
Entry<E> e = header; //得到头部
if (index < (size >> 1)) { //查询速度优化,如果长度是10二进制为1010,右移1位101,index<5从前面开始找,循环到i等于index为止
for (int i = 0; i <= index; i++)
e = e.next;
} else { //如果大于则从后面开始,说明LinkedList是一个圈
for (int i = size; i > index; i--) //从size开始减循环到i>index时,确定e的值,在得到Element
e = e.previous;
}
return e;
}
List
boolean add(E e);添加一个元素
ArrayList
public boolean add(E e) {
ensureCapacity(size + 1); // 扩大数组的空间,如果新加一个,放不下了,则原数组大小*3/2+1扩张
elementData[size++] = e; //第size+1个放入es
return true; //返回成功
}
LinkedList
private Entry<E> addBefore(E e, Entry<E> entry) {//直接调用的addBefore(e,header)在开始的前面加一个,因为是一个圈,所以相当于在最后加了一个
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); //Entry的构造方法(当前值,下一个的值,上一个的值)因为本来就是一个圈,新加入的值的下一个
newEntry.previous.next = newEntry; //就是LinkedList的头,上一个是原来头部的上一个,现在新加进来的上一个和下一个已经关联起来了
newEntry.next.previous = newEntry; //但是原来的投的上一个还是未插入进来的上一个,所以把newEntry的下一个的上一个指向本身,
size++; //把newEntry的下一个的上一个指向本身
modCount++;
return newEntry;
}
List Object[] toArray();
ArrayList
public Object[] toArray() {
return Arrays.copyOf(elementData, size); //Arrays的方法把ArrayList内部属性数组直接复制给新的数组
}
LinkedList
public Object[] toArray() {
Object[] result = new Object[size]; //创建一个与LinkedList等长的数组
int i = 0;
for (Entry<E> e = header.next; e != header; e = e.next)
result[i++] = e.element; //循环List,赋值
return result;
}
boolean remove(Object o);
ArrayList
private void fastRemove(int index) { //通过循环找到与Object相等的下标,在调用这个方法
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, //把下标+1后面的数据加到本数据index后面,然后把最后一个置为空
numMoved);
elementData[--size] = null; // Let gc do its work
}
LinkedList
private E remove(Entry<E> e) { //通过循环找到相等的Entry
if (e == header)
throw new NoSuchElementException();
E result = e.element; //先保存当前element,用于返回
e.previous.next = e.next; //当前的上一个的下一个替换成当前的下一个
e.next.previous = e.previous; //当前的下一个的上一个替换为当前的上一个
e.next = e.previous = null; //当前中的值全部置为null
e.element = null;
size--;
modCount++;
return result;
}
boolean removeAll(Collection<?> c);
AbstractCollection
public boolean removeAll(Collection<?> c) {
boolean modified = false; //是否修改了
Iterator<?> e = iterator();
while (e.hasNext()) { //循环每一个
if (c.contains(e.next())) { //里面是否存在于c
e.remove(); //Iterator删除
modified = true;
}
}
return modified;
}
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet); //删除循环到的最后一个
if (lastRet < cursor)
cursor--; //游标-1
lastRet = -1;
expectedModCount = modCount; //多线程
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
boolean containsAll(Collection<?> c);
public boolean containsAll(Collection<?> c) {
Iterator<?> e = c.iterator();
while (e.hasNext()) //循环C
if (!contains(e.next())) //如果本集合中不包括其中一个则返回false
return false;
return true;
}