迭代器模式可以說(shuō)經(jīng)常在用驼卖,也可以說(shuō)不常用齿梁,他一般用在集合里面的遍歷逞泄。(JDK已經(jīng)幫我們實(shí)現(xiàn)了担租,所以我們經(jīng)常用別人寫(xiě)好的溯香,只是不知道而已)
計(jì)算機(jī)的物理存儲(chǔ)鲫构,只分為2個(gè)類型,隨機(jī)存儲(chǔ)玫坛,順序存儲(chǔ)结笨,JAVA里的集合的典型代表是ArrayList,LinkList,他們的遍歷方式是不同的,如果外部類想要對(duì)他們進(jìn)行遍歷的話湿镀,不同的集合要寫(xiě)不同的算法炕吸,迭代器模式就是解決這個(gè)問(wèn)題(集合你自己去實(shí)現(xiàn)好遍歷,我外部只管調(diào)用你提供方法就好了)
第一步勉痴,手寫(xiě)ArrayList,LinkList源碼實(shí)現(xiàn),首先抽離公共接口為Collection_
public interface Collection_ {
void add(Object o);
int size();
}
arraylist 底層是順序存儲(chǔ)赫模,所以用數(shù)組來(lái)存
public class ArrayList_ implements Collection_{
private Object[] objects = new Object[10];//初始化一個(gè)10個(gè)大小數(shù)組
private int index=0;//記錄數(shù)組大小,同時(shí)也當(dāng)下標(biāo)使用
@Override
public void add(Object o) {
if(index>=objects.length){
//如果放置的元素最后一個(gè)時(shí)候蒸矛,那么先擴(kuò)容為2倍
Object[] newobjects = new Object[objects.length*2];
System.arraycopy(objects,0,newobjects,0,objects.length);
objects=newobjects;
}
objects[index]=o;
index++;
}
@Override
public int size() {
return index;
}
}
linklist 采用鏈表形式瀑罗,先造一個(gè)Node類來(lái)包裝,也就是所謂的單個(gè)鏈條元素
public class Node {
private Object object;
private Node next;
public Node(Object object) {
this.object = object;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public class LinkList_ implements Collection_{
Node head=null;//頭指針
Node tail=null;//尾指針
int size=0;
@Override
public void add(Object o) {
Node node= new Node(o);//鏈表需要Node包裹對(duì)象
if(head==null){
//如果頭指針沒(méi)用持對(duì)象雏掠,當(dāng)作是空表
head=node;
tail=node;
}
tail.setNext(node); //舊的尾節(jié)點(diǎn)保存下一個(gè)節(jié)點(diǎn)的信息斩祭,把新節(jié)點(diǎn)加進(jìn)來(lái)
tail=node;//tail節(jié)點(diǎn)離開(kāi)舊節(jié)點(diǎn),指向新加進(jìn)來(lái)的node
size++;//長(zhǎng)度增加
}
@Override
public int size() {
return size;
}
}
本期主題是迭代器模式乡话,就是要遍歷集合內(nèi)元素摧玫,但是這些集合寫(xiě)法不一樣,不能統(tǒng)一到一個(gè)共同方法绑青,但是可以讓他們都繼承一個(gè)接口诬像,在接口里面他們自己去實(shí)現(xiàn),外面的人只管調(diào)用他們繼承的接口闸婴,不管他們的內(nèi)部是怎么實(shí)現(xiàn)的
//新增接口
public interface Iterator_ {
boolean hasNext();
Object next();
}
//調(diào)整接口
public interface Collection_<E> {
void add(E o);
int size();
Iterator_ iterator();
}
修改后array和link
public class ArrayList_ implements Collection_{
private Object[] objects = new Object[10];//初始化一個(gè)10個(gè)大小數(shù)組
private int index=0;//記錄數(shù)組大小颅停,同時(shí)也當(dāng)下標(biāo)使用
@Override
public void add(Object o) {
if(index>=objects.length){
//如果放置的元素最后一個(gè)時(shí)候,那么先擴(kuò)容為2倍
Object[] newobjects = new Object[objects.length*2];
System.arraycopy(objects,0,newobjects,0,objects.length);
objects=newobjects;
}
objects[index]=o;
index++;
}
@Override
public int size() {
return index;
}
@Override
public Iterator_ iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator implements Iterator_ {
private int currentindex=0;//當(dāng)前索引
@Override
public boolean hasNext() {
if(currentindex>=index)
return false;
return true;
}
@Override
public Object next() {
Object object = objects[currentindex];
currentindex++;
return object;
}
}
}
public class MyLinkList implements ZCollection {
Node head = null;
Node tail = null;
private int size=0;
@Override
public void add(Object o) {
Node n=new Node(o);
if (head == null) {
head=n;
tail=n;
}
tail.setNext(n);
tail=n;
size++;
}
@Override
public int size() {
return size;
}
@Override
public Iterator_ interator() {
return new LinkListIterator();
}
private class LinkListIterator implements Iterator_ {
private int currentindex=0;
@Override
public boolean hasNext() {
if (currentindex >= size) {
return false;
}
return true;
}
@Override
public Object next() {
int offset=0;
Node check = check(offset, head);
currentindex++;
return check;
}
private Node check(int offset, Node node) {
if (offset == currentindex) {
return node;
}else{
return check(++offset,node.getNext());
}
}
}
}
為了更加和jdk 提供的array和link相像掠拳,把Object 對(duì)象統(tǒng)一換成泛型E
public interface Collection_<E> {
void add(E o);
int size();
Iterator_ iterator();
}
public interface Iterator_<E> {
boolean hasNext();
E next();
}
public class ArrayList_<E> implements Collection_<E>{
private E[] objects = (E[]) new Object[10];//初始化一個(gè)10個(gè)大小數(shù)組
private int index=0;//記錄數(shù)組大小癞揉,同時(shí)也當(dāng)下標(biāo)使用
@Override
public void add(E o) {
if(index>=objects.length){
//如果放置的元素最后一個(gè)時(shí)候,那么先擴(kuò)容為2倍
E[] newobjects = (E[]) new Object[objects.length*2];
System.arraycopy(objects,0,newobjects,0,objects.length);
objects=newobjects;
}
objects[index]=o;
index++;
}
@Override
public int size() {
return index;
}
@Override
public Iterator_ iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator<E> implements Iterator_<E> {
private int currentindex=0;//當(dāng)前索引
@Override
public boolean hasNext() {
if(currentindex>=index)
return false;
return true;
}
@Override
public E next() {
E object = (E) objects[currentindex];
currentindex++;
return object;
}
}
}
public class LinkList_<E> implements Collection_<E>{
Node head=null;//頭指針
Node tail=null;//尾指針
int size=0;
@Override
public void add(E o) {
Node node= new Node(o);//鏈表需要Node包裹對(duì)象
if(head==null){
//如果頭指針沒(méi)用持對(duì)象溺欧,當(dāng)作是空表
head=node;
tail=node;
}
tail.setNext(node); //舊的尾節(jié)點(diǎn)保存下一個(gè)節(jié)點(diǎn)的信息喊熟,把新節(jié)點(diǎn)加進(jìn)來(lái)
tail=node;//tail節(jié)點(diǎn)離開(kāi)舊節(jié)點(diǎn),指向新加進(jìn)來(lái)的node
size++;//長(zhǎng)度增加
}
@Override
public int size() {
return size;
}
@Override
public Iterator_ iterator() {
return new LinkListIterator();
}
private class LinkListIterator implements Iterator_ {
private int currentindex=0;
@Override
public boolean hasNext() {
if (currentindex >= size) {
return false;
}
return true;
}
@Override
public Object next() {
int offset=0;
Node node = getNode(offset, head);
return node;
}
private Node getNode(int offset, Node node) {
if (offset == currentindex) {
//相等說(shuō)明指定的就是要的節(jié)點(diǎn)姐刁,否則前進(jìn)一步去拿下一個(gè)節(jié)點(diǎn)
return node;
}else{
return getNode(++offset,node.getNext());
}
}
}
}
最后場(chǎng)景類驗(yàn)證
public class Client {
public static void main(String[] args) {
Collection_<String> mytest=new ArrayList_<>();
for (int i = 0; i < 5; i++) {
mytest.add(i+"");
}
Iterator_ iterator = mytest.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.err.println(next);
}
}
}