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


    接着上篇文章,我们介绍了很多有关于泛型使用和注意的事项,这次将给一个很好的代码实例来演示泛型的有趣性----代码来着《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 keguirong
    10  *
    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 iteration
    18     private int size = 0;
    19     public CoffeeGenerator(int sz){ size = sz;}
    20     //@Override
    21     public Iterator<Coffee> iterator() {
    22         // 直接返回了一个CoffeeIterable
    23         return new CoffeeIterator();
    24     }
    25 
    26     @Override
    27     public Coffee next() {
    28         // TODO Auto-generated method stub
    29         try {
    30             return (Coffee) types[rand.nextInt(types.length)].newInstance();
    31             //Report programmer errors at run time
    32         } catch (Exception e) {
    33             // TODO: handle exception
    34             throw new RuntimeException(e);
    35         }
    36     }
    37 
    38     class CoffeeIterator implements Iterator<Coffee>{
    39 
    40         int count = size;
    41         @Override
    42         public boolean hasNext() {
    43             // TODO Auto-generated method stub
    44             return count >0;
    45         }
    46 
    47         @Override
    48         public Coffee next() {
    49             // TODO Auto-generated method stub
    50             count --;
    51             return CoffeeGenerator.this.next();
    52         }
    53 
    54         @Override
    55         public void remove() {
    56             // TODO Auto-generated method stub
    57             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 0
    Mocha 1
    Americano 2
    Latte 3
    Latte 4
    Americano 5
    Latte 6
    Mocha 7
    Americano 8
    Americano 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 coll
    11      * @param gen
    12      * @param n
    13      * @return
    14      */
    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 t
    16      * @param c
    17      */
    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的Customer
    24         Queue<Customer> line = new LinkedList<Customer>();
    25         Generators.fill(line, Customer.generator(), 15);
    26         //4个ArrayList的tellers
    27         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 Customer1
    Teller2 serves Customer2
    Teller3 serves Customer3
    Teller1 serves Customer4
    Teller1 serves Customer5
    Teller3 serves Customer6
    Teller1 serves Customer7
    Teller2 serves Customer8
    Teller3 serves Customer9
    Teller3 serves Customer10
    Teller2 serves Customer11
    Teller4 serves Customer12
    Teller2 serves Customer13
    Teller1 serves Customer14
    Teller1 serves Customer15
    View Code

    结束


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

  • 相关阅读:
    Java基本数据类型转换
    Java中的数据类型
    Java常见关键字
    HashMap源码分析(jdk 8)
    函数参数
    存储盘在系统中对应的naa号
    Python处理文本换行符
    Python文件操作中的方法:.write()换行
    此示例示意标准输出函数print的用法
    主机端查看到的wwpn 不是以:分割解决办法
  • 原文地址:https://www.cnblogs.com/kgrdomore/p/5835966.html
Copyright © 2020-2023  润新知