遍歷內容
23種設計模式之一,行爲模式之一,主要用在容器遍歷中。返回一個iterator即可遍歷對象
優缺點
一般來說,容器的自動的增刪改由容器本身確定,而去實現遍歷,第一種:有容器本身決定,第二種:由調用者決定。這樣雖然都可以實現遍歷,但是容易引起程序的混淆,一旦添加或者刪除容器也要保存遍歷狀態,容易出錯
把容器的遍歷交給一個Iterator來做,屏蔽聚合對象中的容器實現細節,按順序對集合進行訪問。
把容器的訪問委託給Iterator,進行遍歷。
模擬Collection
package com.Iterator;
public interface Collection {
void add(Object object);
int size();
}
模擬Iterator
public interface Iterator {
Object next();
boolean hasNext();
}
模擬 ArrayList
package com.Iterator;
import com.Iterator.Collection;;
/**
*
* 自定義一個list集合類
*/
public class ArrayList implements Collection{
private Object[] object;
public Object[] getObject() {
return object;
}
public void setObject(Object[] object) {
this.object = object;
}
public ArrayList() {
super();
object = new Object[10];
}
int index = 0;
public void add(Object obj){
if(index == object.length){
Object[] newObject = new Object[object.length *2];
System.arraycopy(object, 0, newObject, 0, object.length);
object = newObject;
}
object[index] = obj;
index ++;
}
public int size(){
return index;
}
public Iterator iterator(){
return new ArrayListIterator();
}
//實現內部類
private class ArrayListIterator implements Iterator{
private int cuurentIndex = 0;
public Object next() {
Object o = object[cuurentIndex];
cuurentIndex++;
return o;
}
@Override
public boolean hasNext() {
if(cuurentIndex >= index){
return false;
}
return true;
}
}
}
模擬 LinkedList
package com.Iterator;
public class LinkedList {
private Node head;
private Node tail;
int index = 0;
public void add(Object obj){
Node n = new Node(obj, null);
if(head == null){
head = n;
tail = n;
return;
}
tail.setNext(n);
tail = n;
index++;
}
public int size(){
return index;
}
//返回一個iterator
public Iterator iterator(){
return new LinkedListIterator();
}
//內部實現類
private class LinkedListIterator implements Iterator{
int currentIndex = 0;
@Override
public Object next() {
Object o = null;
if(head == null)
o = head;
o = head.getNext();
currentIndex++;
return o;
}
@Override
public boolean hasNext() {
if(currentIndex != 0){
return false;
}
return true;
}
}
}
----------
//Node
package com.Iterator;
public class Node {
private Object node ;
private Node next;
public Node(Object node, Node next) {
super();
this.node = node;
this.next = next;
}
public Object getNode() {
return node;
}
public void setNode(Object node) {
this.node = node;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node [node=" + node + ", next=" + next + "]";
}
}
在這裏爲鏈表結構做一個補充
- 第一次添加的鏈表head和tail: 第一次添加時,head和tail都指向同一個對象,
這個時候就應該返回了,我們已經設置好頭部和尾部了
-第二次添加時,在第一次設置頭部和尾部都指向同一個對象,所以在tail.setNext(n),head也已經改變了,head的next也指向n可,再把尾部tail的指向放到n中(這裏爲n做一個特別說明,因爲之前呢head的next也指向n,所以tail的指向n,可以看作是head頭部的next的指向與tail指向的n到最後都指向同一個對象,也可以說tail指向head的next),最後把tail的指向放到n中(n爲一個Node,),
- 注意看變化,在tail的setNext(n)中,tail已經與head都指向同一個對象,這個時候已經改變head的next了,這時在吧tai指向head的next,就形成一個完整的鏈表結構
- 梳理一下:head的next和tail都指向同一個對象,改變tail就等於改變head的next,只不過這個改變是隱藏的,tail.setNext可以看作是head的next.setNext,最後在吧tail指向head的next指向的對象,下次的tail,也就是head的next了。
TestList
import com.Iterator.ArrayList;
import com.Iterator.LinkedList;;
public class TestList {
public static void main(String[] args) {
LinkedList list = new LinkedList();
for(int i= 0;i < 10;i++){
list.add(i);
}
Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println (iterator.next().toString());
}
System.out.println(list.size());
}
}