編輯:關於Android編程
我們這篇博客來介紹一下迭代器模式(Iterator Pattern),又稱為游標(Cursor Pattern)模式,是行為型設計模式之一。迭代器模式算是一個比較古老的設計模式,其源於對容器的訪問,比如 Java 中的 List、Map、數組等,我們知道對容器對象的訪問必然會涉及遍歷算法,我們可以將遍歷的方法封裝在容器中,或者不提供遍歷方法。如果我們將遍歷的方法封裝到容器中,那麼對於容器類來說就承擔了過多的功能,容器類不僅要維護自身內部的數據元素而且還要對外提供遍歷的接口方法,因為遍歷狀態的存儲問題還不能對同一個容器同時進行多個遍歷操作,如果我們不提供遍歷方法而讓使用者自己去實現,又會讓容器的內部細節暴露無遺,正因於此,迭代模式應運而生,在客戶訪問類與容器體之間插入一個第三者——迭代器,很好地解決了上面所述的弊端。
提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。
迭代器模式讓我們能游走於聚合內的每一個元素,而又不暴露其內部的表示,把游走的任務放在迭代器上,而不是聚合上。這樣簡化了聚合的接口和實現,也讓責任各得其所。
迭代器模式使用的場景也很簡單:遍歷一個容器對象時。
迭代器模式角色:
ConcreteIterator.class
public class ConcreteIteratorimplements Iterator { private List list; private int cursor = 0; public ConcreteIterator(List list) { this.list = list; } @Override public boolean hasNext() { return cursor != list.size(); } @Override public T next() { T obj = null; if (this.hasNext()) { obj = this.list.get(cursor++); } return obj; } }
容器類:
Aggregation.class
public interface Aggregation{ void add(T obj); void remove(T obj); Iterator iterator(); }
ConcreteAggregation.class
public class ConcreteAggregationimplements Aggregation { private List list = new ArrayList<>(); @Override public void add(T obj) { list.add(obj); } @Override public void remove(T obj) { list.remove(obj); } @Override public Iterator iterator() { return new ConcreteIterator<>(list); } }
客戶端代碼
public class Client { public static void main(String args[]) { Aggregationa = new ConcreteAggregation<>(); a.add("a"); a.add("b"); a.add("c"); Iterator iterator = a.iterator(); while (iterator.hasNext()) { System.out.print(iterator.next()); } } }
最後結果就是遍歷了一遍:
abc Process finished with exit code 0
迭代器這個模式對於很多開發者來說幾乎不會自己去實現一個迭代器,但是我們平時使用的頻率不會低,在 Android 中,除了各種數據結構體,如 List、Map 等所包含的迭代器外,數據庫查詢的 Cursor 也是一個迭代器。
我們這裡就簡單分析一下 ArrayList 的 Iterator 源碼:
Iterator.class
public interface Iterator{ /** * Returns {@code true} if the iteration has more elements. * (In other words, returns {@code true} if {@link #next} would * return an element rather than throwing an exception.) * * @return {@code true} if the iteration has more elements */ boolean hasNext(); /** * Returns the next element in the iteration. * * @return the next element in the iteration * @throws NoSuchElementException if the iteration has no more elements */ E next(); /** * Removes from the underlying collection the last element returned * by this iterator (optional operation). This method can be called * only once per call to {@link #next}. The behavior of an iterator * is unspecified if the underlying collection is modified while the * iteration is in progress in any way other than by calling this * method. * * @throws UnsupportedOperationException if the {@code remove} * operation is not supported by this iterator * * @throws IllegalStateException if the {@code next} method has not * yet been called, or the {@code remove} method has already * been called after the last call to the {@code next} * method */ void remove(); }
ArrayList.Itr.class
private class Itr implements Iterator{ int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
這就是 ArrayList 迭代器的具體實現,從源碼中我們可以看到有一個 checkForComodification() 函數,拋出的異常 ConcurrentModificationException 應該很多人認識,如果 modCount 不等於 expectedModCount,則拋出 ConcurrentModificationException 異常,一般情況下出現在遍歷的同時調用了 ArrayList.remove 等操作對數據集合進行了更改,例如多線程中當一個線程刪除了元素,由於 modCount 是 AbstarctList 的成員變量,因此可能會導致在其他線程中modCount 和 expectedModCount 值不等。
對於迭代模式來說,其自身優點很明顯:
迭代子模式簡化了聚集的接口,迭代子具備了一個遍歷接口,這樣聚集的接口就不必具備遍歷接口;每一個聚集對象都可以有一個或多個迭代子對象,每一個迭代子的迭代狀態可以是彼此獨立的。因此,一個聚集對象可以同時有幾個迭代在進行之中;由於遍歷算法被封裝在迭代子角色裡面,因此迭代的算法可以獨立於聚集角色變化。而其缺點就是對類文件的增加。其實迭代模式發展至今,幾乎每一種高級語言都有相應的內置實現,對於開發者來說,已經很少會去由自己來實現迭代器了,因此,對於迭代器模式我們更多地是在於了解而非應用。
https://github.com/zhaozepeng/Design-Patterns/tree/master/IteratorPattern
Android中實現圓角圖片的方式有很多種:一、shape二、.9圖三、XferMode四、BitmapShader五、ClipPath其中一、二兩種方法比較簡單粗暴,三
概述Android的消息機制主要值得就是Handler的運行機制,Handler的運行需要底層的MessageQueue和Looper的支撐。MessageQueue即為
使用Material Design 需要api21,即Lollipop/5.0以上 Material Design 為應用提供了:一個新的主題,一些組合Vi
還是先來看看是不是你想要的效果:不廢話,直接上代碼,很簡單,代碼裡都有注釋1 單選public class SingleActivity extends AppCompa