偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

設計模式系列之迭代器模式

開發(fā) 前端
迭代器設計模式在我們業(yè)務場景中自己寫的代碼中 我個人是覺得比較少見的,至少到目前我還沒有怎么發(fā)現(xiàn)有好的業(yè)務場景可以用這個模式,所以這里我就不給大家舉例業(yè)務代碼改造了。

[[406817]]

 Iterator大家應該都很熟悉了,作為Java程序員的我們來說,遍歷集合這也是我們剛開始學習Java知識。

遍歷集合的方式也有很多,比如for循環(huán)、while循環(huán)、foreach循環(huán)、Iterator等。這里的Iterator就是我們設計模式里面的迭代器模式。

這次要跟大家分享的設計模式就是這迭代器模式,雖然很多語言都直接把Iterator封裝到基礎工具類中,但是它的特性你都了解嗎?

本期大綱

定義

迭代器大家都很熟悉,那么什么叫迭代器?它的目的又是什么呢?

  • 定義:我們可以用相同的方式處理集合,無論它是列表還是數(shù)組,它都提供了一種迭代其元素而不用暴露其內(nèi)部結(jié)構的機制,更重要的是,不同的類型的集合都可以使用相同的統(tǒng)一機制,這種機制則被稱為 迭代器模式。
  • 目的:提供一種順序遍歷聚合對象元素,而不暴露其內(nèi)部實現(xiàn)的方法。

以上定義來之設計模式之美

解析圖:

  • Aggregate(抽象容器):負責提供創(chuàng)建具體迭代器角色的接口,對應于java.util.Collection接口。
  • Iterator(抽象迭代器):迭代器的抽象類,它定義遍歷容器對象的操作以及返回對象的操作
  • ConcreteAggregate(具體容器):主要是可以實現(xiàn)內(nèi)部不同的結(jié)構。但會暴露處理遍歷容器的具體迭代器。
  • ConcreteIterator(具體迭代器):處理特定的具體容器類的具體迭代器,實際上對于每個容器具體容器,都必須實現(xiàn)一個具體的迭代器。

整個圖看起來其實就兩個東西,一個容器,一個迭代器。

代碼實現(xiàn)

這次就不舉列了。直接手寫一個迭代器,我們再測試一下。

主要還是理解迭代器到底是干嘛用的:

  • 能在不暴露集合底層表現(xiàn)形式 (列表、 棧和樹等) 的情況下遍歷集合中所有的元素

話不多說,還是直接上手擼代碼

  1. public interface Aggregate { 
  2.     // 添加元素 
  3.     void add(Object object); 
  4.  
  5.     // 移除元素 
  6.     void remove(Object object); 
  7.  
  8.     // 迭代器 
  9.     Iterator iterator(); 

按照上面的類圖,先是創(chuàng)建抽象容器,定義幾個基本添加刪除元素方法,以及迭代器

  1. public interface Iterator<E> { 
  2.     // 判斷容器是否有值 
  3.     boolean hasNext(); 
  4.  
  5.     // 把游標執(zhí)向下一個指針 
  6.     void next(); 
  7.  
  8.     // 當前遍歷的數(shù)據(jù) 
  9.     E currentItem(); 

其次 再試創(chuàng)建抽象迭代器,遍歷容器中的數(shù)據(jù)

  1. public class ConcreteAggregate implements Aggregate { 
  2.     private ArrayList arrayList = new ArrayList(); 
  3.  
  4.     @Override 
  5.     public void add(Object object) { 
  6.         this.arrayList.add(object); 
  7.     } 
  8.  
  9.     @Override 
  10.     public void remove(Object object) { 
  11.         this.arrayList.remove(object); 
  12.     } 
  13.  
  14.     @Override 
  15.     public Iterator iterator() { 
  16.         return new ConcreteIterator(this.arrayList); 
  17.     } 

開始定義我們具體的容器了,內(nèi)部定一個ArrayList容器,用來存放數(shù)據(jù),當然這里大家也可以改成其他的容器 比如說用Vector 或者其他的 棧、 樹、 圖 等

  1. public class ConcreteIterator<E> implements Iterator<E> { 
  2.  
  3.     private int cursor; // 游標 
  4.     private ArrayList arrayList; 
  5.  
  6.     public ConcreteIterator(ArrayList arrayList) { 
  7.         this.cursor = 0; 
  8.         this.arrayList = arrayList; 
  9.     } 
  10.  
  11.     @Override 
  12.     public boolean hasNext() { 
  13.         if (this.cursor == this.arrayList.size()) { 
  14.             return false
  15.         } 
  16.         return true
  17.     } 
  18.  
  19.     @Override 
  20.     public void next() { 
  21.         cursor++; 
  22.         System.out.println(cursor + "   cursor"); 
  23.     } 
  24.  
  25.     @Override 
  26.     public E currentItem() { 
  27.         if (cursor >= arrayList.size()) { 
  28.             throw new NoSuchElementException(); 
  29.         } 
  30.         E e = (E) arrayList.get(cursor); 
  31.         this.next(); 
  32.         return e; 
  33.     } 
  34.    
  35.    // 測試demo 
  36.     public static void main(String[] args) { 
  37.         Aggregate aggregate = new ConcreteAggregate(); 
  38.         aggregate.add("java"); 
  39.         aggregate.add("c++"); 
  40.         aggregate.add("php"); 
  41.         aggregate.add("敖丙"); 
  42.  
  43.         Iterator iterator = aggregate.iterator(); 
  44.         while (iterator.hasNext()) { 
  45.             System.out.println(iterator.currentItem()); 
  46.         } 
  47.       // 結(jié)果:1    java 
  48.       //      2     c++ 
  49.       //      3     php 
  50.       //      4     敖丙 
  51.     } 

最后就是實現(xiàn)具體的迭代器了, 在currentItem里面根據(jù)遍歷的游標,獲取數(shù)組里面的值

同時在main方法里面就是測試demo了,以上就是簡單的手擼迭代器了。

這里面我們其實還可以有其它的各種特別的玩法,比如說怎么實現(xiàn)暫停遍歷等,只有了解內(nèi)部實現(xiàn),我們才能改造出符合當前所需要的業(yè)務代碼。

Java中的迭代器

在Java的中也有迭代器,java.util.Iterator類以及java.util.Collection,就是典型的迭代器喝容器的列子,接下來看看具體的源碼

當next沒有值的時候則會拋出NoSuchElementException異常信息,上面的手擼異常也是根據(jù)這個來的

在Java中 常見的 List、Set、Queue都是extend Collection(容器),而Collection又定義迭代器Iterator,這就是能直接使用的原因了。

Java集合分析

上面我們看完了Java中的迭代器,不知道,大家注意了沒有,我們在使用迭代器的時候是不能再對集合進行增減操作的,否則就會拋出ConcurrentModificationException異常

那么問題來了,為什么會有這個異常信息呢?

看過ArrayList源碼的同學都知道底層是數(shù)據(jù)結(jié)構中的數(shù)組結(jié)構的,所以我們看下接下來圖結(jié)構

假設現(xiàn)在開始在遍歷當前這個數(shù)組,當從第一步執(zhí)行到第二步,都是正常運行的,假設現(xiàn)在執(zhí)行完第二步,開始走第三步時

刪除 java這個元素,數(shù)組為了保持存儲數(shù)據(jù)的連續(xù)性,當刪除java數(shù)據(jù)時,是會發(fā)生數(shù)組元素的遷移的。所以正常步驟3應該是遍歷到aobing元素的變成當前數(shù)組元素已經(jīng)是ao bing了。

導致了數(shù)組會發(fā)生ao bing沒有遍歷到,因為數(shù)據(jù)遷移而丟失了。

同樣的假設在后面添加元素按照向后遷移,還能遍歷到,那如過插入的數(shù)據(jù)是在已經(jīng)遍歷的之前呢?

這樣整個遍歷就變成不可預估了。

  1. public static void main(String[] args) { 
  2.       List<String> aggregate = new ArrayList(); 
  3.       aggregate.add("java"); 
  4.       aggregate.add("c++"); 
  5.       aggregate.add("php"); 
  6.       aggregate.add("敖丙"); 
  7.       Iterator<String> iterator = aggregate.iterator(); 
  8.       while (iterator.hasNext()) { 
  9.           iterator.remove(); // 添加這行代碼 java.lang.IllegalStateException 
  10.           System.out.println(iterator.next()); 
  11.           iterator.remove(); // 正常 
  12.       } 
  13.   } 

再來看這個測試demo,同樣都是調(diào)用remove方法,不同的地方結(jié)果不一樣,這也就是剛好印證上面的圖體現(xiàn)的問題,所以要解決這個問題,要么就是遍歷的時候不允許增刪元素,要么是增刪元素之后讓遍歷報錯。

通過上面的列子已經(jīng)了解了迭代器的原理以及實現(xiàn),大家可以根據(jù)自己所需要的場景改造迭代器,很多公司的一些自己的框架或者工具類等等都是通過現(xiàn)有框架源碼進行改造而來。

迭代器的優(yōu)點:

  • 迭代器模式封裝集合內(nèi)部的復雜數(shù)據(jù)結(jié)構,不用關心需要遍歷的對象。
  • 符合單一職責原則以及開閉原則
  • 可以對遍歷進行把控暫停或者繼續(xù)

總結(jié)

迭代器設計模式在我們業(yè)務場景中自己寫的代碼中 我個人是覺得比較少見的,至少到目前我還沒有怎么發(fā)現(xiàn)有好的業(yè)務場景可以用這個模式,所以這里我就不給大家舉例業(yè)務代碼改造了。(畢竟不能因為設計模式而強行設計)

跟大家分享迭代器主要是想讓大家了解Java集合遍歷怎么實現(xiàn)的,方便我們提升自己以后的看源碼的能力,以及提升自己的設計能力。

后面就再跟大家再聊聊動態(tài)代理設計模式,就不會再詳細講了其他的模式了,因為本身不怎么常見,作為了解還是會和大家做一個總結(jié)分享。

今天的迭代器模式到此結(jié)束,我是敖丙,你知道的越多,你不知道的越多,我們下期見!!!

 

責任編輯:姜華 來源: 三太子敖丙
相關推薦

2020-11-06 09:01:46

迭代器模式

2010-04-29 08:53:11

PHP迭代器模式

2021-06-09 08:53:34

設計模式策略模式工廠模式

2012-01-13 15:59:07

2020-11-09 08:20:33

解釋器模式

2021-03-05 07:57:41

設計模式橋接

2021-01-21 05:34:14

設計模式建造者

2023-09-04 13:14:00

裝飾器設計模式

2021-07-08 11:28:43

觀察者模式設計

2021-02-18 08:39:28

設計模式場景

2020-05-25 10:20:19

享元模式場景

2022-01-19 08:21:12

設計裝飾器模式

2023-12-13 13:28:16

裝飾器模式Python設計模式

2022-01-12 13:33:25

工廠模式設計

2020-11-04 08:54:54

狀態(tài)模式

2020-11-03 13:05:18

命令模式

2020-10-23 09:40:26

設計模式

2010-04-21 08:38:18

解釋器模式PHP設計模式

2021-09-29 13:53:17

抽象工廠模式

2022-01-14 09:22:22

設計模式橋接
點贊
收藏

51CTO技術棧公眾號