編輯:關於android開發
迭代器模式,又叫做游標模式,是行為型設計模式之一。我們知道對容器對象的訪問必然會涉及遍歷算法,我們可以將遍歷的方法封裝在容器中,或者不提供遍歷方法,讓使用容器的人自己去實現去吧。這兩種情況好像都能夠解決問題。
然而在前一種情況,容器承受了過多的功能,它不僅要負責自己“容器”內的元素維護(添加、刪除等等),而且還要提供遍歷自身的接口;而且由於遍歷狀態保存的問題,不能對同一個容器對象同時進行多個遍歷。第二種方式倒是省事,卻又將容器的內部細節暴露無遺。
正因於此,迭代器模式應運而生,在客戶訪問類與容器體之間插入一個第三者–迭代器,很好的解決了上述弊端。
提供一種方法順序訪問一個容器對象中的各個元素,而又不需要暴露該對象的內部表示。
遍歷一個容器對象時。
用書中的例子:小民和小輝分別在公司兩個事業部,某天老板安排任務讓他們倆統計一下各自部門的員工數據。
員工實體類:
public class Employee {
private String name;// 姓名
private int age;// 年齡
private String sex;// 性別
private String position;// 職位
public Employee(String name, int age, String sex, String position) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.position = position;
}
// 簡化代碼,省略setter和getter方法
@Override
public String toString() {
return "Employee{" + "name='" + name + '\'' + ", age=" + age + ", sex="
+ sex + ", position='" + position + '\'' + "}";
}
}
小輝部門:
public class CompanyHui {
private Employee[] array = new Employee[3];
public CompanyHui(){
array[0] = new Employee("輝哥", 28, "男", "程序猿");
array[1] = new Employee("小紅", 23, "男", "程序猿");
array[2] = new Employee("小輝", 25, "男", "程序猿");
}
public Employee[] getEmployees(){
return array;
}
}
小民部門:
public class CompanyMin {
private List list = new ArrayList<>();
public CompanyMin(){
list.add(new Employee("小民", 26, "男", "程序猿"));
list.add(new Employee("小芸", 22, "女", "測試"));
list.add(new Employee("小方", 18, "女", "測試"));
list.add(new Employee("可兒", 21, "女", "設計"));
list.add(new Employee("朗情", 19, "女", "設計")); //吐槽一下,為什麼就小民一個男的,小輝部門全男的。
}
public List getEmployees(){
return list;
}
}
Boss查看:
public class Boss {
public static void main(String[] args) {
CompanyHui hui = new CompanyHui();
Employee[] huiList = hui.getEmployees();
for(int i = 0; i < huiList.length; i++){
System.out.println(huiList[i]);
}
CompanyMin min = new CompanyMin();
List minList = min.getEmployees();
for(int i = 0; i < minList.size(); i++){
System.out.println(minList.get(i).toString());
}
}
}
結果:
Employee{name='輝哥', age=28, sex=男, position='程序猿'}
Employee{name='小紅', age=23, sex=男, position='程序猿'}
Employee{name='小輝', age=25, sex=男, position='程序猿'}
Employee{name='小民', age=26, sex=男, position='程序猿'}
Employee{name='小芸', age=22, sex=女, position='測試'}
Employee{name='小方', age=18, sex=女, position='測試'}
Employee{name='可兒', age=21, sex=女, position='設計'}
Employee{name='朗情', age=19, sex=女, position='設計'}
這樣看似也沒有問題,但是如果有多個部門,每個部門有各自的實現,那麼我們就要在Boss類中增加一遍遍歷邏輯,這樣Boss類的功能會越來越多,同時暴露了內部細節。那麼我們需要定義一個迭代器接口:
public interface Iterator {
/**
* 是否還有下一個元素
*
* @return true表示有,false表示沒有
*/
boolean hasNext();
/**
* 返回當前元素,並將位置移至下一位
*/
Object next();
}
小民的迭代器:
public class MinIterator implements Iterator{
private List list;
private int position;
public MinIterator(List list){
this.list = list;
}
@Override
public boolean hasNext() {
return !(position > list.size() - 1 || list.get(position) == null);
}
@Override
public Object next() {
Employee e = list.get(position);
position++;
return e;
}
}
小輝的迭代器:
public class HuiIterator implements Iterator{
private Employee[] array;
private int position;
public HuiIterator(Employee[] array){
this.array = array;
}
@Override
public boolean hasNext() {
return !(position > array.length - 1 || array[position] == null);
}
@Override
public Object next() {
Employee e = array[position];
position++;
return e;
}
}
定義容器類的接口
public interface Company {
/**
* 返回一個迭代器對象
*
* @return 迭代器對象
*/
Iterator iterator();
}
修改一下之前的兩個容器類:
public class CompanyHui implements Company{
private Employee[] array = new Employee[3];
public CompanyHui(){
array[0] = new Employee("輝哥", 28, "男", "程序猿");
array[1] = new Employee("小紅", 23, "男", "程序猿");
array[2] = new Employee("小輝", 25, "男", "程序猿");
}
public Employee[] getEmployees(){
return array;
}
@Override
public Iterator iterator() {
return new HuiIterator(array);
}
}
public class CompanyMin implements Company{
private List list = new ArrayList<>();
public CompanyMin(){
list.add(new Employee("小民", 26, "男", "程序猿"));
list.add(new Employee("小芸", 22, "女", "測試"));
list.add(new Employee("小方", 18, "女", "測試"));
list.add(new Employee("可兒", 21, "女", "設計"));
list.add(new Employee("朗情", 19, "女", "設計"));
}
public List getEmployees(){
return list;
}
@Override
public Iterator iterator() {
return new MinIterator(list);
}
}
Boss查看:
public class Boss {
public static void main(String[] args) {
CompanyHui hui = new CompanyHui();
check(hui.iterator());
CompanyMin min = new CompanyMin();
check(min.iterator());
}
private static void check(Iterator iterator){
while (iterator.hasNext()) {
System.out.println(iterator.next().toString());
}
}
}
結果不變,就不重復寫了。
當我們使用SQLiteDatabase的query方法查詢數據庫時,會返回一個Cursor游標對象,該游標的實質就是一個具體的迭代器,我們可以使用它來遍歷數據庫查詢所得的結果集。
迭代器模式發展至今,幾乎所有的高級語言都有相應的內置實現,對於開發者而言,已經極少會自己去實現迭代器了,所以本章內容更多的是了解而非應用。
(1)符合面向對象設計原則中的單一職責原則。
(2)支持對容器對象的多種遍歷。弱化了容器類與遍歷算法之間的關系。
(1)類文件的增加。
(3)會出現ConcurrentModificationException異常。
(2)遍歷過程是一個單向且不可逆的遍歷。
Android基礎入門教程——9.2 MediaPlayer播放音頻與視頻 本節引言: 本節帶來的是Android多媒體中的——
關於eclipse android 在manifest改app應用包名注意事項,androidmanifest在我剛學android 時候,然後立即就做項目。那時連ecl
Android性能優化之Splash頁應該這樣設計 目前SplashActivity的設計 目前市場上的應用在啟動時基本上都會先啟動一個SplashActivity,作為
OuNews 簡單的新聞客戶端應用源碼,ounews源碼 一直想練習MVP模式開發應用,把學習的RxJava、Retrofit等熱門的開源庫結合起來,