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

接着上篇文章,我们介绍了很多有关于泛型使用和注意的事项,这次将给一个很好的代码实例来演示泛型的有趣性----代码来着《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 {

}

package Generic.Coffee;

public class Mocha extends Coffee {

}

package Generic.Coffee;

public class Americano extends Coffee{

}

package Generic.Coffee;

public class Cappuccino extends Coffee {

}

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

例子二:服务器接客



代码思路如下:

  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

结束



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

时间: 2024-08-06 20:03:02

泛型全面分析和应用(二)的相关文章

linux程序分析工具介绍(二)—-ldd,nm

本文要介绍的ldd和nm是linux下,两个用来分析程序很实用的工具.ldd是用来分析程序运行时需要依赖的动态库的工具:nm是用来查看指定程序中的符号表相关内容的工具.下面通过例子,分别来介绍一下这两个工具: 1. ldd, 先看下面的例子, 用ldd查看cs程序所依赖的动态库: [email protected]:~/Public$ ldd cs linux-gate.so.1 => (0xffffe000) libz.so.1 => /lib/libz.so.1 (0xb7f8c000)

Android 4.2 Bluetooth 分析总结(二) 蓝牙enable 的整个过程

转载请标明出处:Android 4.2 Bluetooth 分析总结(二) 蓝牙enable 的整个过程 现在开始我们分析 Android4.2 Bluetooth 打开的整个过程,由于是新手,难免有很多错误,记录只是为了以后方便查找,如发错误敬请指出. 我们整个分析过程有可能有点繁琐,但请仔细阅读,读完之后必然发现还是会有一点点收获的,虽然写的不好.搜先我们上一份enable 打开蓝牙整个过程的打印:然后我们跟踪打印来窥探 Android4.2Bluetooth 工作的流程. D/Blueto

对于ArrayList中的泛型进行分析

package cn.lonecloud.reflect; import java.lang.reflect.Method; import java.util.ArrayList; public class checkList { public static void main(String[] args) throws Exception{ ArrayList list=new ArrayList(); ArrayList<String> list2=new ArrayList<>

iOS Crash 分析(文二)-崩溃日志组成

iOS Crash 分析(文二)-崩溃日志组成 现在我们看一个淘宝iOS主客崩溃的例子: ### 1.进程信息 ### Incident Identifier: E4201F10-6F5F-40F9-B938-BB3DA8ED7D50 CrashReporter Key: TODO Hardware Model: iPhone4,1 Process: Taobao4iPhone [3538] Path: /var/mobile/Applications/E3B51E77-D44D-4B3E-87

&quot;别踩白块儿&quot;游戏源代码分析和下载(二)

四.游戏交互实现 1.前面已经介绍在 Block 类实现了每个block的触碰监听,block 实现触碰监听,当按下时,调起在GameScene中实现的touchBlock方法.下面来看改方法的实. /** * 点击到Block时进行的逻辑处理 * * @param pBlock *            所点击的block */ public void touchBlock(Block pBlock) { if (gameStatus == ConstantUtil.GAME_START) {

Hadoop源代码分析(三二)

搞定ClientProtocol,接下来是DatanodeProtocol部分.接口如下: public DatanodeRegistration register(DatanodeRegistration nodeReg ) throws IOException 用亍DataNode向NameNode登记.输入和输出参数都是DatanodeRegistration,类图如下: 前面讨论DataNode的时候,我们已绊讲过了DataNode的注册过程,我们来看NameNode的过程.下面是主要步

Python 爬虫知识点 - 淘宝商品检索结果抓包分析(续二)

一.URL分析 通过对“Python机器学习”结果抓包分析,有两个无规律的参数:_ksTS和callback.通过构建如下URL可以获得目标关键词的检索结果,如下所示: https://s.taobao.com/search?data-key=s&data-value=44&ajax=true&_ksTS=1482325509866_2527&callback=jsonp2528&q=Python机器学习&imgfile=&js=1&stat

车道检测源码分析系列(二)

本节分析一个国人开发的简单的车道检测程序(不涉及跟踪) simple_lane_tracking 源码地址 作者主页 概述 采用opencv2编写 C++ 算法核心步骤 提取车道标记特征,封装在laneExtraction类中 车道建模(两条边,单车道),封装在laneModeling类中 对于断断续续的斑点车道标记(虚线)使用RANSAC匹配直线,对每幅图像,检测结果可能是感兴趣的左右车道都检测到或者全都没检测到 主程序框架 track.cpp 主程序依次读入源文件夹下的图片,进行处理后输出到

java B2B2C电子商务平台分析之十二-----Spring Cloud Sleuth

一.简介 Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案,并且兼容支持了 zipkin,你只需要在pom文件中引入相应的依赖即可.愿意了解源码的朋友直接求求交流分享技术:二一四七七七五六三三 二.服务追踪分析 微服务架构上通过业务来划分服务的,通过REST调用,对外暴露的一个接口,可能需要很多个服务协同才能完成这个接口功能,如果链路上任何一个服务出现问题或者网络超时,都会形成导致接口调用失败.随着业务的不断扩张,服务之间互相调用会越来越复杂. 三.术语 Spr