成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文徹底搞明白迭代器模式

開發 前端
對于一個類來說,對于其屬性或狀態的遍歷是類的一種行為。但是,這種行為不屬于核心業務操作。因此,迭代器模式的本質上是將這種遍歷行為通用化,這樣也可以為調用方提供統一的訪問接口。?

本篇講解Java設計模式中的迭代器模式,分為定義、模式應用前案例、結構、模式應用后案例、適用場景、模式可能存在的困惑和本質探討7個部分。

定義

迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不需暴露該對象的內部表示。

在新的分類方式中,迭代器模式被劃分至類之間的交互類別中,其簡化的是調用方對一個或一組對象遍歷行為的交互。

模式應用前案例

在銀行業務領域中,銀行包含很多客戶,而一個客戶又可能包含多個賬戶。下面以這個案例進行說明。先來看一下未使用迭代器模式之前的代碼實現。

public class Account {//賬戶類
private final String accountNumber;
private final double balance;

public Account(String accountNumber, double balance) {
this.accountNumber = accountNumber;
this.balance = balance;
    }

// 省略其他屬性和方法

public String getAccountNumber(){
return this.accountNumber;
    }

public double getBalance(){
return this.balance;
    }
}

public class Customer {//客戶類
private final String name;
private final List<Account> accounts;

public Customer(String name) {
this.name = name;
this.accounts = new ArrayList<>();
    }

public void addAccount(Account account) {
this.accounts.add(account);
    }

// 遍歷賬戶信息
public void displayAccounts() {
        System.out.println("Customer: " + this.name);
//for (Account account : this.accounts) {//底層使用Iterator實現
for(int i=0;i<this.accounts.size();i++) {
            System.out.println("Account Number: " + this.accounts.get(i).getAccountNumber() + ", Balance: " + this.accounts.get(i).getBalance());
        }
    }
}

public class Bank {//銀行集合類

private final List<Customer> customers;

public Bank(){
this.customers = new ArrayList<>();
    }

// 添加顧客
public void addCustomer(Customer customer){
this.customers.add(customer);
    }

// 顯示所有客戶的帳號信息
public void displayAllCustomersAndAccounts() {
//for (Customer customer : this.customers) {//底層使用Iterator實現
for(int i=0;i<this.customers.size();i++) {
this.customers.get(i).displayAccounts();
        }
    }
}

public class Client {//調用方代碼

public static void main(String[] args) {

        Bank bank= new Bank();
        Customer customer1 = new Customer ("Sun");
        customer1.addAccount(new Account( "1234" ,1000.0));
        customer1.addAccount(new Account( "5678",500.0));

        Customer customer2 = new Customer("Wang");
        customer2.addAccount(new Account( "9012" ,200.0));
        customer2.addAccount(new Account( "3456",40000));

        bank.addCustomer(customer1);
        bank.addCustomer(customer2);

        bank.displayAllCustomersAndAccounts();

    }
}

對于迭代器模式,Java語言中的集合已經內置支持。在上述代碼中,注釋掉的增強的for循環方式(如for (Account account : this.accounts)),其底層也會轉換成Iterator方式。

因此,主要是對比for(int i=0;i<size;i++)這種方式和Iterator迭代器方式之間的優劣。

結構

迭代器模式的上述結構是一個通用的結構,其代碼實現如下。

public interface Iterator<T> {
T next();
boolean hasNext();
}

public class ConcreteIterator<T> implements Iterator {
private int currentIndex = 0;
private T[] t;
public ConcreteIterator(T[] t) {
this.t = t;
    }

@Override
public Object next() {
return t[currentIndex++];
    }

@Override
public boolean hasNext() {
return currentIndex < t.length;
    }
}

public interface Aggregate {
Iterator createIterator();
}

public class ConcreteAggregate implements Aggregate {
public String[] items;

public ConcreteAggregate() {
        items = new String[10];
for(int i=0;i<items.length;i++) {
            items[i] = "str"+i;
        }
    }

@Override
public Iterator createIterator() {
return new ConcreteIterator<String>(items);
    }

}

public class Client {
public static void main(String[] args) {
        ConcreteAggregate aggregate = new ConcreteAggregate();
        Iterator<String> iterator =  aggregate.createIterator();
while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

模式應用后案例

由于Java語言已經內置迭代器實現。上面的銀行領域案例,如果應用迭代器模式,代碼實現如下。

public class Account {//賬戶類
private final String accountNumber;
private final double balance;

public Account(String accountNumber, double balance) {
this.accountNumber = accountNumber;
this.balance = balance;
    }

// 省略其他屬性和方法

public String getAccountNumber(){
return this.accountNumber;
    }

public double getBalance(){
return this.balance;
    }
}

public class Customer {//客戶類


private final String name;
private final List<Account> accounts;

public Customer(String name) {
this.name = name;
this.accounts = new ArrayList<>();
    }

public void addAccount(Account account) {
this.accounts.add(account);
    }

public Iterator<Account> iterator() {
return this.accounts.iterator();
    }

public String getName() {
return this.name;
    }

// 遍歷賬戶信息
public void displayAccounts() {
//循環賬戶
        Iterator<Account> acctIterator = this.iterator();
while(acctIterator.hasNext()){
            Account acount = acctIterator.next();
            System.out.println("Acount Number:"+acount.getAccountNumber() + ", Balance: "+acount.getBalance());
        }
    }
}

public class Bank implements Iterable<Customer>{

private final List<Customer> customers;

public Bank() {
this.customers =new ArrayList<>();
    }

// 添加顧客
public void addCustomer(Customer customer){
this.customers.add(customer);
    }

@Override
public Iterator<Customer> iterator(){
return this.customers.iterator();
    }

// 顯示所有客戶的帳號信息
public void displayAllCustomersAndAccounts() {
        Iterator<Customer> customerIterator = this.iterator();
//循環客戶
while(customerIterator.hasNext()) {
            Customer customer = customerIterator.next();
            System.out.println("Customer: " +customer.getName());

            customer.displayAccounts();
        }
    }
}

public class Client {//調用方代碼

public static void main(String[] args) {

        Bank bank = new Bank();

        Customer customer1 = new Customer("Sun");
        customer1.addAccount(new Account("1234", 1000.0));
        customer1.addAccount(new Account("5678", 500.0));

        Customer customer2= new Customer ("Wang");
        customer2.addAccount(new Account( "9012" ,200.0));
        customer2.addAccount(new Account( "3456",40000));

        bank.addCustomer(customer1);
        bank.addCustomer(customer2);


        bank.displayAllCustomersAndAccounts();

    }
}

Java語言中提供了Iterable接口,然后重寫里面的iterator方法。通過該方法就可以得到一個Iterator對象,然后可以利用這個Iterator對象就可以依次訪問集合中的元素。

適用場景

迭代器模式適用于以下場景:

1、訪問一個聚合對象的內容而無需暴露它的內部表示

2、支持對聚合對象的多種遍歷方式,如樹、圖等

3、對遍歷不同的聚合結構提供一個統一的接口

模式可能存在的困惑

困惑1:增強for循環(如for(obj:ObjList))與Iterator迭代器方式有何區別?

增強for循環方式相當于Java語言中的一種語法糖。在編譯階段,會轉換成Iterator方式實現。

困惑2:普通for循環(如for(int i=0;i<size;i++))似乎也比較簡潔,Iterator相比有什么優勢?

針對數組、鏈表等簡單的數據結構,兩種循環方式其實體現不出優勢。但是,對于樹和圖等復雜數據結構,普通for循環很難支持。

例如,對于樹(Tree)這類數據結構,至少包括以下三種遍歷方式:

1)前序遍歷(Preorder Traversal):先訪問根節點,然后遞歸地前序遍歷左子樹和右子樹;

2)中序遍歷(Inorder Traversal):先遞歸地中序遍歷左子樹,然后訪問根節點,最后遞歸地中序遍歷右子樹;

3)后序遍歷(Postorder Traversal):先遞歸地后序遍歷左子樹和右子樹,最后訪問根節點。

對于圖(Graph)這類數據結構,至少也要支持以下兩種遍歷方式

1)深度優先搜索(Depth-First Search, DFS):從起始頂點出發,在走過一條路徑上所有未被標記過的頂點之前不回退;

2)廣度優先搜索(Breadth-First Search, BFS):從起始頂點開始向外層擴散搜索,并且按照距離排序依次進行探索。

此外,由于迭代器是一個家族類,最上層是一個Iterable接口,后續也可以靈活擴展其他更高效的遍歷方式。

本質

對于一個類來說,對于其屬性或狀態的遍歷是類的一種行為。但是,這種行為不屬于核心業務操作。

因此,迭代器模式的本質上是將這種遍歷行為通用化,這樣也可以為調用方提供統一的訪問接口。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2024-05-13 10:45:25

中介模式面向對象數量

2024-05-10 08:43:04

外觀模式接口系統

2024-05-09 09:09:19

組合模式對象

2024-05-17 10:08:59

享元模式分類方式

2024-05-15 17:41:37

備忘錄模式多線程

2019-08-27 14:46:59

ElasticSearES數據庫

2020-07-10 08:03:35

DNS網絡ARPAne

2023-05-29 08:45:45

Java注解數據形式

2019-09-09 11:02:17

Nginx進程模型

2023-03-13 08:12:37

Golang編程路徑問題

2019-10-28 10:19:27

JVM 類加載器Java

2021-05-06 08:03:07

IPIP網絡模式calicok8s

2023-11-06 09:06:54

分布式一致性數據

2024-02-23 12:11:53

裝飾器模式對象

2022-05-30 10:37:35

分布式事務反向補償

2020-12-07 06:19:50

監控前端用戶

2021-07-08 10:08:03

DvaJS前端Dva

2021-06-30 08:45:02

內存管理面試

2022-06-07 10:13:22

前端沙箱對象

2020-03-18 14:00:47

MySQL分區數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人在线观看免费 | 成年人免费网站 | 狠狠操狠狠| 91精品国产91久久久久久密臀 | 日本一区二区在线视频 | 成人亚洲性情网站www在线观看 | 337p日韩| 一区二区视频在线观看 | 亚洲国产一 | 国产精品夜间视频香蕉 | 中文字幕免费观看 | xxxxx黄色片| 国产精品久久久久久久午夜 | 亚洲视频中文字幕 | 欧美精品一 | 91精品久久久久久久99 | 九九99精品 | 国产一区二区三区 | 成人国产在线视频 | 国产成人黄色 | 亚洲国产一区二区在线 | 国户精品久久久久久久久久久不卡 | 日韩欧美手机在线 | 国产成人福利 | 亚洲欧美一区二区三区国产精品 | 亚洲毛片| 91av久久久| 亚洲天堂一区二区 | 久久精品亚洲精品国产欧美 | 精品久久视频 | 欧美黄色一级毛片 | 在线观看日本高清二区 | 香蕉久久久 | 精品日韩一区二区三区 | 91免费在线 | 在线观看亚洲精品 | 日韩欧美专区 | 亚洲精品电影在线 | 日韩国产欧美 | a级片播放| 国产成人精品综合 |