以前我以為只有Python才會有generator,看來當時的我才年輕,后來認真研讀《Thinking in Java》之后大有感悟,原來Java亦有generator,故做一次記錄分享。過程中主要通過具體代碼展示筆記簡單比較Python generator來加深理解。
1、什么是Java Generator
關於Generator我的理解主要如下,如有不妥,希望大家指正!
(1)python中這樣理解:在一個過程中一邊循環一邊計算返回,能讓單獨的循環功能模塊(也可以理解為一個單線程)不斷“掛起”生成結果而不會一直循環到return為止。 其中能說明的就是求斐波拉契數列,關鍵字yield是不斷返回下一個b的值,也就是return next()
注意:有些博主以為Python協程中有yield關鍵字,所以跟generator是一回事,但是我不這么認為。
1 def fib(max): 2 n, a, b = 0, 0, 1 3 while n < max: 4 #之前是print (b) 5 yield b 6 a, b = b, a + b 7 n = n + 1
輸出結果:
#第一次next():1 print(fib(1)) #第二次next():2 print(fib(2)) #第三次next():3 print(fib(2))
(2)Java中這樣理解:將泛型應用於接口,接口必須有返回類型為泛型T的next()方法,是一種專門負責創建對象的類。在很多設計模式都會用到(比如工廠方法模式),類似於Iterable對象中使用使用next()不斷獲得下一個值,這里泛型接口中的next()方法返回創建對象。
2、實現一個CommonGenerator通用生成器
實現一個通用生成器,通過next不斷返回一個對象的實例
interface Generator
1 /** 2 * Generator泛型接口 3 * @author Jian 4 * @param <T> 5 */ 6 public interface Generator<T> { 7 T next(); 8 }
CommonGenerator:
1 /** 2 * CommonGenerator繼承Generator泛型接口,實現通過next不斷返回實例 3 * @author Jian 4 * @param <T> 5 */ 6 public class CommonGenerator<T> implements Generator<T>{ 7 private Class<T> type; 8 /** 9 * CommonGenerator Constructor 10 * @param type 11 */ 12 public CommonGenerator(Class<T> type) { 13 this.type = type; 14 } 15 /** 16 * next()不斷返回xxx.class的對象 17 */ 18 @Override 19 public T next() { 20 try { 21 //傳入class返回對象 22 return type.newInstance(); 23 } catch (Exception e) { 24 throw new RuntimeException(e); 25 } 26 } 27 /** 28 * @param type 傳入創建類xxx.class 29 * @return CommonGenerator實例 30 */ 31 public static <T> Generator<T> create(Class<T> type){ 32 return new CommonGenerator<T>(type); 33 } 34 }
TestObject:
1 /** 2 * 測試類:統計返回測試類的引用實例的數目 3 * @author Jian 4 * 5 */ 6 public class TestObject { 7 private static long counter= 0;//統計計數器 8 public String toString() { 9 //注意:這里return中不能用this,否則會出現遞歸 10 return "TestObject " + (counter++); 11 } 12 }
MainClass:
1 public class MainClass { 2 public static void main(String[] args) { 3 Generator<TestObject> generator = new CommonGenerator<>(TestObject.class); 4 for(int i=0;i<3;i++) { 5 //generator.next()返回對象,輸出調用toString方法 6 System.out.println(generator.next()); 7 } 8 } 9 }
輸出:
TestObject 0 TestObject 1 TestObject 2