首页 > 代码库 > 泛型全面分析和应用(二)

泛型全面分析和应用(二)

接着上篇文章,我们介绍了很多有关于泛型使用和注意的事项,这次将给一个很好的代码实例来演示泛型的有趣性----代码来着《Java编程思想》

 

例子一:再来一杯coffee


 

代码的思路如下:

  1. 构建一个Generator的接口,这个接口用来实现“繁殖功能”的作用
  2. 定义一个Coffee类,接着用几种Coffee子类继承这个Coffee父类
  3. 构建一个CoffeeGenerator的类,这个类有两个特点,一个是实现了Generator<Coffee>和Iterable<Coffee>,这就是泛型的两种实现“繁殖功能”的关键了。

 

Generator接口

1 package Generic.Coffee;2 3 public interface Generator<T> {4 5     T next();6 }

Coffee父类

 1 package Generic.Coffee; 2  3 public class Coffee { 4  5     private static long counter = 0; 6     private final long id = counter++; 7     public String toString(){ 8         return getClass().getSimpleName() + " " + id; 9     }10 }

几种Coffee子类

技术分享
package Generic.Coffee;public class Latte extends Coffee {}
View Code
技术分享
package Generic.Coffee;public class Mocha extends Coffee {}
View Code
技术分享
package Generic.Coffee;public class Americano extends Coffee{}
View Code
技术分享
package Generic.Coffee;public class Cappuccino extends Coffee {}
View Code

CoffeeGenerator实例

 1 package Generic.Coffee; 2  3 import java.util.Iterator; 4 import java.util.Random; 5  6 /** 7  * 这里两种繁殖Coffee的方法,一种是实现了有next()的Generator,另外一种是实现有遍历功能Iterable 8  * 这里两种都是运用了泛型,在Generator和Iterable的泛型类型中加入了Coffee 9  * @author keguirong10  *11  */12 public class CoffeeGenerator implements Generator<Coffee>,Iterable<Coffee>{13 14     private Class[] types = {Latte.class,Mocha.class,Americano.class,Cappuccino.class};15     private static Random rand = new Random(47);16     public CoffeeGenerator(){}17     //For iteration18     private int size = 0;19     public CoffeeGenerator(int sz){ size = sz;}20     //@Override21     public Iterator<Coffee> iterator() {22         // 直接返回了一个CoffeeIterable23         return new CoffeeIterator();24     }25 26     @Override27     public Coffee next() {28         // TODO Auto-generated method stub29         try {30             return (Coffee) types[rand.nextInt(types.length)].newInstance();31             //Report programmer errors at run time32         } catch (Exception e) {33             // TODO: handle exception34             throw new RuntimeException(e);35         }36     }37 38     class CoffeeIterator implements Iterator<Coffee>{39 40         int count = size;41         @Override42         public boolean hasNext() {43             // TODO Auto-generated method stub44             return count >0;45         }46 47         @Override48         public Coffee next() {49             // TODO Auto-generated method stub50             count --;51             return CoffeeGenerator.this.next();52         }53 54         @Override55         public void remove() {56             // TODO Auto-generated method stub57             throw new UnsupportedOperationException();58         }59     }60     61     public static void main(String[] args) {62         CoffeeGenerator gen = new CoffeeGenerator();63         for(int i = 0; i < 5; i ++)64             System.out.println(gen.next());65         //如果没有实现了Iterable<Coffee>接口,下面的for循环是不能进行的66         for(Coffee c : new CoffeeGenerator(5))67             System.out.println(c);68     }69 }

运行结果

技术分享
Americano 0Mocha 1Americano 2Latte 3Latte 4Americano 5Latte 6Mocha 7Americano 8Americano 9
View Code

 

 

 

例子二:服务器接客


 

代码思路如下:

  1. 和“例子一”一样,需要一个Generator的有next()的接口,和一个有自动填充功能的类
  2. 客户能自动生成,需要有实现了Generator的实现内部类
  3. 当然,服务器也有相应的实现,实现方式却是另一种方式。
  4. 关联客户和服务器

Generator的接口

1 package Generic.Coffee;2 3 public interface Generator<T> {4 5     T next();6 }

 

自动填充类

 1 package Generic.Coffee; 2  3 import java.util.ArrayList; 4 import java.util.Collection; 5  6 public class Generators { 7  8     /** 9      * 一个参数是Collection泛型的容器,一个是生成Generator的类,一个是要填充数量10      * @param coll11      * @param gen12      * @param n13      * @return14      */15     public static <T> Collection<T>  fill(Collection<T> coll,Generator<T> gen ,int n){16         for(int i = 0 ; i < n ; i++)17             coll.add(gen.next());18         return coll;19     }20     21 }

 

客户类

 1 public class Customer { 2  3     private static long counter = 1; 4     private final long id = counter++; 5     public Customer(){} 6     public String toString(){ 7         return "Customer"+ id ; 8     } 9     //一种是Generator的方法,内部类10     public static Generator<Customer> generator(){11         return new Generator<Customer>(){12             public Customer next(){ return new Customer();}13         };14     }15     16 }

 

服务类

 1 class Teller{ 2     private static long counter = 1; 3     private final long id = counter ++; 4     private Teller(){} 5     public String toString(){return "Teller" + id;} 6     //A single Generator object; 7     //一种是新建一个Generator,这个Generator是一个内部类 8     public static Generator<Teller> generator = new Generator<Teller>(){ 9         public Teller next(){return new Teller();}10     };11 }

 

实现两者的关联

 1 package Generic; 2  3 import java.util.ArrayList; 4 import java.util.LinkedList; 5 import java.util.List; 6 import java.util.Queue; 7 import java.util.Random; 8  9 import Generic.Coffee.Generators;10 11 public class BankTeller {12 13     /**14      * 关联客户和服务的方法15      * @param t16      * @param c17      */18     public static void server(Teller t ,Customer c){19         System.out.println( t + " serves " + c);20     }21     public static void main(String[] args) {22         Random rand = new Random(47);23         //15个LinkList的Customer24         Queue<Customer> line = new LinkedList<Customer>();25         Generators.fill(line, Customer.generator(), 15);26         //4个ArrayList的tellers27         List<Teller> tellers = new ArrayList<Teller>();28         Generators.fill(tellers, Teller.generator, 4);29         //随机分配30         for(Customer c : line){31             server(tellers.get(rand.nextInt(tellers.size())),c);32         }33     }34 }

 

运行结果

技术分享
Teller3 serves Customer1Teller2 serves Customer2Teller3 serves Customer3Teller1 serves Customer4Teller1 serves Customer5Teller3 serves Customer6Teller1 serves Customer7Teller2 serves Customer8Teller3 serves Customer9Teller3 serves Customer10Teller2 serves Customer11Teller4 serves Customer12Teller2 serves Customer13Teller1 serves Customer14Teller1 serves Customer15
View Code

 

 

结束


 

  好了,其实很多情况我们都用到了泛型,但是却不知道自己使用到了。泛型具有限定性,规范性,最重要的一点是 模拟代表性,可以被范围内的多种参数类型使用同一个方法,在上一篇已经介绍了,这一篇展示2个有趣的例子就好了,嘻嘻嘻

 

泛型全面分析和应用(二)