public class ArrayList { Object[] objects = new Object[10]; int index = 0; public void add(Object o) { if(index == objects.length) { Object[] newObjects = new Object[objects.length * 2]; System.arraycopy(objects, 0, newObjects, 0, objects.length); objects = newObjects; } objects[index] = o; index ++; } public int size() { return index; }
public class LinkedList { Node head = null; Node tail = null; int size = 0; public void add(Object o) { Node n = new Node(o, null); if(head == null) { head = n; tail = n; } tail.setNext(n); tail = n; size ++; } public int size() { return size; }
public class Node { public Node(Object data, Node next) { super(); this.data = data; this.next = next; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } private Object data; private Node next; }
小结:现在就让我们来分析下链表是怎么回事,下面是我目前的对链表的认识。
1.链表是数据结构,C++使用指针来完成这种结构,而JAVA在则使用引用,本质当然也是指针
2.本例模拟linkedList使用的就是链表结构,JAVA中在链表结构中的各个对象有个特点就是
在保持自身数据的同时,还保持了对其他对象的应用
LinkedList add方法示意图
第一次add
第二次add
第三次ADD
通过这样的方式我们就实现了linkedList存储数据,但是有个问题,如果我们要变量ArrayList和LinkedList,他们的机制是不一样的,怎么办呢?
这就是迭代模式要解决的问题,迭代模式与策略模式类似,策略模式是对算法的接口化,而迭代模式则是对容器便利的接口化
下面我们改造ArrarList
public interface Collection { void add(Object o); int size(); Iterator iterator(); }
public interface Iterator { Object next(); boolean hasNext(); }
public class ArrayList implements Collection { Object[] objects = new Object[10]; int index = 0; public void add(Object o) { if(index == objects.length) { Object[] newObjects = new Object[objects.length * 2]; System.arraycopy(objects, 0, newObjects, 0, objects.length); objects = newObjects; } objects[index] = o; index ++; } public int size() { return index; } public Iterator iterator() { return new ArrayListIterator(); }
小结:使用者本来是要对不同的容器编写不同的便利方式,这样给使用者造成了一定的麻烦,我们就想
能否对不同的容器,让使用者以一种相同的方式遍历呢,这就是迭代模式。我们要遍历集合
无非就是判断集合是否还有元素和返回元素操作,我们把这两种行为抽象为接口的两个方法
我们遍历时对接口编程就可以了。具体怎么遍历,不同的容器需要提供给我一个他的Iterator就可以了。
总而言之,言而总之,迭代模式是为容器而生的,是对各种容器遍历的接口化,便于用户的使用
最后一个问题 如何选择linkedList和ArrayList
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
3.LinkedList不支持高效的随机元素访问。
4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。