<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 遍歷聚合對象中的元素——迭代器模式(五) 5 JDK內置迭代器 為了讓開發人員能夠更加方便地操作聚合對象,在Java、C#等編程語言中都提供了內置迭代器。在Java集合框架中,常用的List和Set等聚合類都繼承(或實現)了java.util.Collection接口,在Collection接口中聲明了如下方法(部分): ``` package java.util; public interface Collection<E> extends Iterable<E> { …… boolean add(Object c); boolean addAll(Collection c); boolean remove(Object o); boolean removeAll(Collection c); boolean remainAll(Collection c); Iterator iterator(); …… } ``` 除了包含一些增加元素和刪除元素的方法外,還提供了一個iterator()方法,用于返回一個Iterator迭代器對象,以便遍歷聚合中的元素;具體的Java聚合類可以通過實現該iterator()方法返回一個具體的Iterator對象。 JDK中定義了抽象迭代器接口Iterator,代碼如下所示: ``` package java.util; public interface Iterator<E> { boolean hasNext(); E next(); void remove(); } ``` 其中,hasNext()用于判斷聚合對象中是否還存在下一個元素,為了不拋出異常,在每次調用next()之前需先調用hasNext(),如果有可供訪問的元素,則返回true;next()方法用于將游標移至下一個元素,通過它可以逐個訪問聚合中的元素,它返回游標所越過的那個元素的引用;remove()方法用于刪除上次調用next()時所返回的元素。 Java迭代器工作原理如圖5所示,在第一個next()方法被調用時,迭代器游標由“元素1”與“元素2”之間移至“元素2”與“元素3”之間,跨越了“元素2”,因此next()方法將返回對“元素2”的引用;在第二個next()方法被調用時,迭代器由“元素2”與“元素3”之間移至“元素3”和“元素4”之間,next()方法將返回對“元素3”的引用,如果此時調用remove()方法,即可將“元素3”刪除。 ![](http://img.blog.csdn.net/20130815233601859?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTG92ZUxpb24=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 圖5 Java迭代器示意圖 如下代碼片段可用于刪除聚合對象中的第一個元素: ``` Iterator iterator = collection.iterator(); //collection是已實例化的聚合對象 iterator.next(); // 跳過第一個元素 iterator.remove(); // 刪除第一個元素 ``` 需要注意的是,在這里,next()方法與remove()方法的調用是相互關聯的。如果調用remove()之前,沒有先對next()進行調用,那么將會拋出一個IllegalStateException異常,因為沒有任何可供刪除的元素。 如下代碼片段可用于刪除兩個相鄰的元素: ``` iterator.remove(); iterator.next(); //如果刪除此行代碼程序將拋異常 iterator.remove(); ``` 在上面的代碼片段中如果將代碼iterator.next();去掉則程序運行拋異常,因為第二次刪除時將找不到可供刪除的元素。 在JDK中,Collection接口和Iterator接口充當了迭代器模式的抽象層,分別對應于抽象聚合類和抽象迭代器,而Collection接口的子類充當了具體聚合類,下面以List為例加以說明,圖6列出了JDK中部分與List有關的類及它們之間的關系: ![](http://img.blog.csdn.net/20130815233742437?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTG92ZUxpb24=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 圖6 Java集合框架中部分類結構圖 (注:為了簡化類圖,本圖省略了大量方法) 在JDK中,實際情況比圖6要復雜很多,在圖6中,List接口除了繼承Collection接口的iterator()方法外,還增加了新的工廠方法listIterator(),專門用于創建ListIterator類型的迭代器,在List的子類LinkedList中實現了該方法,可用于創建具體的ListIterator子類ListItr的對象,代碼如下所示: ``` public ListIterator<E> listIterator(int index) { return new ListItr(index); } listIterator()方法用于返回具體迭代器ListItr類型的對象。在JDK源碼中,AbstractList中的iterator()方法調用了listIterator()方法,如下代碼所示: ``` public Iterator<E> iterator() { return listIterator(); } ``` 客戶端通過調用LinkedList類的iterator()方法,即可得到一個專門用于遍歷LinkedList的迭代器對象。 大家可能會問?既然有了iterator()方法,為什么還要提供一個listIterator()方法呢?這兩個方法的功能不會存在重復嗎?干嘛要多此一舉? 這是一個好問題。我給大家簡單解釋一下為什么要這樣設計:由于在Iterator接口中定義的方法太少,只有三個,通過這三個方法只能實現正向遍歷,而有時候我們需要對一個聚合對象進行逆向遍歷等操作,因此在JDK的ListIterator接口中聲明了用于逆向遍歷的hasPrevious()和previous()等方法,如果客戶端需要調用這兩個方法來實現逆向遍歷,就不能再使用iterator()方法來創建迭代器了,因為此時創建的迭代器對象是不具有這兩個方法的。我們只能通過如下代碼來創建ListIterator類型的迭代器對象: ``` ListIterator i = c.listIterator(); ``` 正因為如此,在JDK的List接口中不得不增加對listIterator()方法的聲明,該方法可以返回一個ListIterator類型的迭代器,ListIterator迭代器具有更加強大的功能。 思考 為什么使用iterator()方法創建的迭代器無法實現逆向遍歷? 在Java語言中,我們可以直接使用JDK內置的迭代器來遍歷聚合對象中的元素,下面的代碼演示了如何使用Java內置的迭代器: ``` import java.util.*; class IteratorDemo { public static void process(Collection c) { Iterator i = c.iterator(); //創建迭代器對象 //通過迭代器遍歷聚合對象 while(i.hasNext()) { System.out.println(i.next().toString()); } } public static void main(String args[]) { Collection persons; persons = new ArrayList(); //創建一個ArrayList類型的聚合對象 persons.add("張無忌"); persons.add("小龍女"); persons.add("令狐沖"); persons.add("韋小寶"); persons.add("袁紫衣"); persons.add("小龍女"); process(persons); } } ``` 在靜態方法process()中使用迭代器Iterator對Collection對象進行處理,該代碼運行結果如下: ``` 張無忌 小龍女 令狐沖 韋小寶 袁紫衣 小龍女 ``` 如果需要更換聚合類型,如將List改成Set,則只需更換具體聚合類類名,如將上述代碼中的ArrayList改為HashSet,則輸出結果如下: ``` 令狐沖 張無忌 韋小寶 小龍女 袁紫衣 ``` 在HashSet中合并了重復元素,并且元素以隨機次序輸出,其結果與使用ArrayList不相同。由此可見,通過使用迭代器模式,使得更換具體聚合類變得非常方便,而且還可以根據需要增加新的聚合類,新的聚合類只需要實現Collection接口,無須修改原有類庫代碼,符合“開閉原則”。 練習 > 在Sunny軟件公司開發的某教務管理系統中,一個班級(Class in School)包含多個學生(Student),使用Java內置迭代器實現對學生信息的遍歷,要求按學生年齡由大到小的次序輸出學生信息。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看