- 在ArrayList中有两个主要的成员变量(还有一个是serialVersionUID,序列化的时候用的),分别是
private transient Object[] elementData; private int size;
看到这两个字段,相信大家就能大概了解这个类的工作方式了。在无参构造ArrayList的时候,ArrayList是默认size=10的,在之后调用add()方法的时候,如过size不够了会new一个比当前Object[]数组的更大的Object[]数组,然后调用Arrays.copyOf()方法,覆盖掉原来的Object[]数组。
- 在LInkedList中,同样有两个主要的成员变量,并且它还有一个关键的内部类,如下:
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; } }
相信大家看到这些代码的时候也差不多理解了LInkedList的工作方式了。在这里再介绍一下在LinkedList中添加元素,先上源码:
public boolean add(E e) { addBefore(e, header); return true; } private Entry<E> addBefore(E e, Entry<E> entry) { Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); newEntry.previous.next = newEntry; newEntry.next.previous = newEntry; size++; modCount++; return newEntry; }
java里面的容器可以说是除了String之外用的最多的类了。容器分为两种,一种是可以遍历的,也就是继承了Iterable接口的,以List为代表;另一种就是不可遍历的,以Map为代表。他们的关系如下:
这篇文章我主要跟大家分享一下我对java.util.List以及他对应的继承类的认识。
Java中的线性表
List就是数据结构里面常说的线性表,他有两种实现方式,分别是顺序表(ArrayList)和链表(LinkedList),这两种表比较来说,ArrayList在随机访问元素时很方便,而在List中间插入和移除元素的时候比较慢,LinkedList则正好相反。
ArrayList和LInkedList的工作方式
代码可能理解起来还是不清楚,上图:
这就是LinkedList添加元素的全过程。
List里面的内部类Iterator
Collection不同于Map的地方就是Collection可遍历,而Map可以根据key来找对应的value。
在List中,遍历器iterator是通过内部类来实现的。Iterator我们用的不过两个方法,hasNext()来判断它是否有下一个值,next()来取得它的下一个值。这两个方法相信大家都不用我多讲,他还有另一个方法,就是remove(),他会移除你当前遍历的元素的前一个元素,当你iteraotr没有开始遍历元素的时候调用remove()会抛出异常。
简单,不多说。