1. 程式人生 > >Java設計模式之迭代器模式(五)

Java設計模式之迭代器模式(五)

迭代器模式:提供一種方法順序訪問一個集合物件中的各個元素,而又不需要暴漏物件的內部表示。

合理組織資料的結構以及相關操作時程式設計的一個重要方面,比如在程式設計中經常會使用諸如連結串列、散列表等資料結構。連結串列和散列表等資料結構都是可以存放若干個物件的集合,其區別時按著不同的方式來儲存物件。我們希望無論何種集合,應當允許程式以一種統一的方式遍歷集合中的物件,而不需要知道這些物件在集合中時如何表示儲存的。

迭代器模式是遍歷集合的一種成熟模式,迭代器模式的關鍵是將遍歷集合的任務交給一個稱作迭代器的物件。

包含角色:

  1、集合(Aggregate):一個介面,規定了集合需要實現的操作。
             2、具體集合(ConcreteArrregate):具體集合是實現集合介面的類的例項,具體集合按著一定的結構儲存物件,具體集合應當有一個方法,該方法返回一個針對該集合的具體迭代器。
             3、迭代器(Iterator): 一個介面,規定了遍歷具體集合的方法,比如next()方法。
            4、具體迭代器(ConcreteIterator): 實現集合介面的類的例項。具體迭代器在實現迭代器 介面所規定的遍歷集合的方法時,比如next()方法,要保證next()方法的首次呼叫將按著集合 的資料結構找到該集合中的一個物件,而且每當找到集合中的一個物件,立刻根據該集合的儲存結構得到待遍歷的後繼物件的引用,並保證依次呼叫next()方法可以遍歷集合。

 優點:
              1、使用者使用迭代器訪問集合中的物件,而不需要知道這些物件在集合中時如何表示以及儲存的。
              2、使用者可以同時使用多個迭代器遍歷一個集合。

 適用情景:
            1、讓使用者訪問一個集合中的物件,但不想暴露物件在集合中的儲存結構。
            2、希望對遍歷不同的集合提供一個統一的介面。 
        
           簡單的例子:現在有若干個學生,有姓名、學號和出生日期等屬性。
                 (1) 使用連結串列存放學生物件。
                 (2) 用一個散列表和一個樹集存放連結串列中的物件。
                 (3) 使用散列表查詢某個學生。
                 (4) 通過樹集將學生按成績排序。
                  
     設計實現

:這裡設計三個類。其中UseSet類包含連結串列、散列表和樹集。Application負責建立Student的例項,並新增到UseSet所包含的集合中,UseSet提供了按Student的number屬性查詢
               Student例項方法,也提供了按score屬性進行排序的方法。

public class Student implements Comparable<Object>{

	String number;
	String name;
	double score = 0;
	
	public Student() {}

	public Student(String number, String name, double score) {
		this.number = number;
		this.name = name;
		this.score = score;
	}
	
	public int compareTo(Object b) {
		Student st = (Student) b;
		
		if (Math.abs(this.score-st.score) <= 1/10000) return 1;
		
		return (int)(1000 * (this.score - st.score));	
	}

	public String getNumber() {
		return number;
	}

	public String getName() {
		return name;
	}

	public double getScore() {
		return score;
	}
}

public class UseSet {

	LinkedList<Student> list;
	Hashtable<String, Student> table;
	TreeSet<Student> tree;
	
	public UseSet(){
		list = new LinkedList<Student>();
		table = new Hashtable<String, Student>();
		tree = new TreeSet<Student>();
	}
	
	public void addStudent(Student stu) {
		list.add(stu);
		update();
	}

	public void findStudent(String num) {
		
		Student stu = table.get(num);
		
		String number = stu.getNumber();
		String name = stu.getName();
		double score = stu.getScore();
		
		System.out.println("學號:" + number + "姓名:" + name + "分數:" + score);
	}
	
	public void printStudentByScore() {
		
	      Iterator<Student> iterator = tree.iterator();
		
	      while(iterator.hasNext()) {
		    Student student = iterator.next();
	            String number = student.getNumber();
		    String name = student.getName();
		    double score = student.getScore();
		    System.out.println("學號:" + number + "姓名:" + name + "分數:" + score);
		}
	}
	
	private void update() {
		
		tree.clear();
		Iterator<Student> iterator = list.iterator();
		while(iterator.hasNext()) {
			Student student = iterator.next();
			String number = student.getNumber();
			table.put(number, student);
			tree.add(student);
		}
	}
}

public class Application {

	public static void main(String[] args) {
		
		UseSet useSet = new UseSet();
		useSet.addStudent(new Student("001", "雷霆", 78.89));
		useSet.addStudent(new Student("002", "火箭", 95.53));
		useSet.addStudent(new Student("003", "勇士", 68.12));
		useSet.addStudent(new Student("004", "騎士", 81.25));
		useSet.addStudent(new Student("005", "灰熊", 74.32));
		useSet.addStudent(new Student("006", "馬刺", 87.23));
		useSet.addStudent(new Student("007", "湖人", 71.96));
		
		String n = "003";
		System.out.println("查詢學號為"+n+"的學生:");
		useSet.findStudent(n);
		
		System.out.println("將學生按成績排列:");
		useSet.printStudentByScore();
	}
}

執行結果: