JAVA范例 十四)泛型
第14章 泛型
14.1 泛型基础
实例255 一个关于泛型的简单例子
import java.util.Date;public class MyFirstGeneric<T> {T t; //t的类型是T,现在不能具体确定它的类型,需要到创建对象时才能确定MyFirstGeneric(T t) {// 创建该类的构造方法为T对象赋值this.t = t;}// 这个方法的返回类型也是TT getT() {return t;}// 显示T的类型void printType() {System.out.println("Type of T is:" + t.getClass().getName());}public static void main(String args[]) {// 声明一个String类型的Generic变量MyFirstGeneric<String> str;// 创建一个String类型的Generic对象str = new MyFirstGeneric<String>("这是一个简单的泛型实例");// 输出它的一些信息str.printType();String string = str.getT();System.out.println("\tstring=" + string);// 声明一个Date类型的Generic变量MyFirstGeneric<Date> sobj;// 创建一个Date类型的Generic对象sobj = new MyFirstGeneric<Date>(new Date());// 输出它的一些信息sobj.printType();String time = sobj.getT().toGMTString();System.out.println("\ttime=" + time);}}
?
实例256 带两个类型参数的泛型
public class MoreParameters<T, V> {T t;V v;// 构造方法也可以使用这两个类型参数MoreParameters(T t1, V v1) {t = t1;v = v1;}// 显示T和V的类型void printTypes() {System.out.println("参数T的对象类型为: " + t.getClass().getName());System.out.println("参数V的对象类型为: " + v.getClass().getName());}T getT() {return t;}V getV() {return v;}public static void main(String args[]) {MoreParameters<Integer, Double> tv; // 指定类型参数的实际类型// 构造方法中需要再次指定类型参数,同时还要传递实际参数tv = new MoreParameters<Integer, Double>(100, 12.56);tv.printTypes();int num = tv.getT();System.out.println("num变量中的值为: " + num);double dou = tv.getV();System.out.println("dou变量中的值为:" + dou);}}
?
实例257 有界类型程序示例
//有界类型程序示例public class BoundedType {public static void main(String args[]) {System.out.println("有界类型程序示例如下:");Integer inums[] = { 1, 2, 3, 4, 5 };//创建一个Integer类型的数组MyTypes<Integer> iobj = new MyTypes<Integer>(inums);//使用泛型对象System.out.println("\tint型数据的求和结果为:" + iobj.summation());Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };MyTypes<Double> dobj = new MyTypes<Double>(dnums);//创建一个Double类型的数System.out.println("\n\tdouble型数据的求和结果为:" + dobj.summation());}}class MyTypes<T extends Number> {T[] nums;//定义一个Number类的数组MyTypes(T[] obj) {//为该数组赋值nums = obj;}double summation() {//对参数进行求和运算double sum = 0.0;for (int i = 0; i < nums.length; ++i)sum += nums[i].doubleValue(); //将Number类数组中的对象转换成double类型并依次相加求和return sum ;}}
?
实例258 通配符使用示例
import java.util.*;//通配符参数使用示例public class Wildcard {public static void main(String args[]) {Integer Ints[] = { 1, 2, 3, 4, 5 };// 定义Integer对象数组并初始化Symbol<Integer> integer = new Symbol<Integer>(Ints);// 创建Integer泛型对象Double Dous[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };// 定义Double对象数组并初始化Symbol<Double> douObject = new Symbol<Double>(Dous);// 创建Double泛型对象douObject.printMessage(integer); // integer和douObject的类型不相同List<String> list1 = new ArrayList<String>();// 定义一个List泛型对象,添加的元素是String类型的// 向List对象中添加元素list1.add("String");list1.add("你好");list1.add("世界真大啊");List<?> list2 = list1;// 声明一个List列表中元素为任何类型的泛型对象,并将list1赋给list2System.out.println("列表List对象list2中的元素如下:");for (int i = 0; i < list2.size(); i++) {System.out.println("\t" + list2.get(i));// 将list2中的元素输出}}}class Symbol<T extends Number> {T[] nums;Symbol(T[] obj) {nums = obj;}void printMessage(Symbol<?> sb) { // 这里使用了类型通配符System.out.println("对象型参数sb的参数类型是:" + sb.getClass().getName());}}
?
实例259 泛型方法使用示例
import java.util.Date;//泛型方法的使用示例public class GenericMethod {// 定义泛型方法,有一个形式参数用类型参数T来定义public static <T> void genericMethods(T t, char n) {T t1 = t; // 局部变量也可以用类型参数T来定义System.out.println("[1] " + n + "的对象类型为:" + t1.getClass().getName());}public static <T> void genericMethods(T t) {System.out.println("\n[2] " + t + "的对象类型为:" + t.getClass().getName());}public static void main(String args[]) {Date date = new Date();Character k = new Character('A');// 用两种不同的方法调用泛型方法GenericMethod.<Character> genericMethods(k, 'B');genericMethods(date);}}
?
实例260 泛型接口示例
//泛型接口的使用示例public class GenericInterface {public static void main(String args[]) {Double doubleArrays[] = { 56.5, 58.127, 56.2, 5.569, 825.0, 12.36,510.89 };// 创建一个Double类型的数组并初始化Character charArrays[] = { 'A', 'w', 'z', 'Z', 'b', 'u', 'x' };// 创建一个Character类型的数组并初始化ComparableElement<Double> iob = new ComparableElement<Double>(doubleArrays);// 创建Double类型的泛型对象ComparableElement<Character> cob = new ComparableElement<Character>(charArrays);// 创建Character类型的泛型对象// 调用MaxOrMin接口中的min()和max()System.out.println("在Integer数组中,求元素最大值,max= " + iob.max());System.out.println("在Integer数组中,求元素最小值为,min= " + iob.min());System.out.println("在Character数组中,求元素最大值,max= " + cob.max());System.out.println("在Character数组中,求元素最小值为,min= " + cob.min());}}interface MaxOrMin<T extends Comparable<T>> {// 创建一个泛型接口// 定义两个泛型方法:min()和max()T min();T max();}// 声明一个ComparableElement类继承于Comparable类并实现MaxOrMin接口class ComparableElement<T extends Comparable<T>> implements MaxOrMin<T> {T[] mm;ComparableElement(T[] ob) {mm = ob;}public T min() {// 重写MaxOrMin接口中的min()方法,求出数组中的最小值T t = mm[0];for (int i = 1; i < mm.length; ++i)if (mm[i].compareTo(t) < 0)t = mm[i];return t;}public T max() {// 重写MaxOrMin接口中的max()方法,求出数组中的最大值T t = mm[0];for (int i = 1; i < mm.length; ++i)if (mm[i].compareTo(t) > 0)t = mm[i];return t;}}
?
实例261 泛型实现坐标打印
/** * Created by IntelliJ IDEA. User: leizhimin Date: 2007-9-18 Time: 16:09:37 * 三种坐标,用泛型实现坐标打印 */public class CoorGeneric {static void showXY(GenericCoords<?> c) {// 定义泛型方法,利用通配符设置参数C的类型为XL并显示类XL中的变量X和Y的值System.out.println("X Y 坐标轴:");for (int i = 0; i < c.gcs.length; i++) {System.out.println(c.gcs[i].x + " " + c.gcs[i].y);}}static void showXYZ(GenericCoords<? extends XYZ> c) {System.out.println("X Y Z 坐标轴:");// 定义泛型方法,利用通配符设置参数C的类型为XYZ并显示类XYZ中的变量X、Y和Z的值for (int i = 0; i < c.gcs.length; i++) {System.out.println(c.gcs[i].x + " " + c.gcs[i].y + " "+ c.gcs[i].z);}}static void showAll(GenericCoords<? extends XYZT> c) {System.out.println("X Y Z T 坐标轴:");// 定义泛型方法,利用通配符设置参数C的类型为XYZT并显示类XYZT中的变量X、Y、Z和T的值for (int i = 0; i < c.gcs.length; i++) {System.out.println(c.gcs[i].x + " " + c.gcs[i].y + " "+ c.gcs[i].z + " " + c.gcs[i].t);}}public static void main(String args[]) {XY td[] = { new XY(0, 0), new XY(7, 9), new XY(18, 4), new XY(-1, -23) };GenericCoords<XY> gcd1 = new GenericCoords<XY>(td);System.out.println("GenericCoords类对象gcd2中的内容:");showXY(gcd1);XYZT fd[] = { new XYZT(1, 2, 3, 4), new XYZT(6, 8, 14, 8),new XYZT(22, 9, 4, 9), new XYZT(3, -2, -23, 17) };GenericCoords<XYZT> gcd2 = new GenericCoords<XYZT>(fd);System.out.println("GenericCoords类对象gcd2中的内容:");showXY(gcd2);showXYZ(gcd2);showAll(gcd2);}}class XY {// 表示只有XY坐标的类int x, y;public XY(int x, int y) {// 为变量X、Y赋值this.x = x;this.y = y;}}class XYZ extends XY {// 表示只有XYZ坐标的类int z;public XYZ(int x, int y, int z) {super(x, y);// 调用父类的构造方法this.z = z;}}class XYZT extends XYZ {// 表示只有XYZT坐标的类,其中X:横坐标,Y:纵坐标 Z:垂直坐标,T:空间int t;public XYZT(int x, int y, int z, int t) {super(x, y, z);// 调用父类的构造方法this.t = t;}}/** * 存放泛型坐标的(数据结构)类 */class GenericCoords<T extends XY> {// 定义泛型类,设置其参数类型为XYT[] gcs;public GenericCoords(T[] gcs) {this.gcs = gcs;}}
?
14.2 泛型类的继承
实例262 继承泛型类示例
import java.util.Date;//继承泛型类public class GenericClass {public static void main(String args[]) {System.out.println("以泛型类为父类的实现方法如下:");// 创建子类的对象,它需要传递两个参数,Date类型给父类,自己使用String类型Child<Date, String> cd = new Child<Date, String>(new Date(),"当前系统的时间为: ");System.out.print("\t" + cd.getDob());System.out.println(cd.getOb());}}class Child<T, U> extends Father<T> {U u;public Child(T t1, U u1) {super(t1); // 传递参数给父类u = u1; // 为自己的成员赋值}public U getDob() {return u;}}class Father<T> { // 定义一个泛型类T t;public Father(T t) {this.t = t;}public Father() {t = null;}public T getOb() {return t;}}
?
实例263 继承非泛型类示例
//继承非泛型类示例public class NonGenericcClass {public static void main(String args[]) {System.out.println("继承非泛型类的实现方法如下:");doNonGeneric<String> oa = new doNonGeneric<String>("doNonGeneric类的值为: ", 125);System.out.print("\t" + oa.getOb());System.out.println(oa.getNum());}}class NonGeneric {// 创建父类对象,此类并不是泛型类double num;public NonGeneric(double n) {// 设置变量num的值等于传入的参数值num = n;}public NonGeneric() {// 设置变量num的默认值为0.0num = 0.0;}public double getNum() {// 返回变量num的当前值return num;}}class doNonGeneric<T> extends NonGeneric {// 定义一个继承于NonGeneric的子类。该类被声明为泛型类T ob;public doNonGeneric(T ob, double n) {super(n);// 将传入的参数值赋给父类this.ob = ob;// 将对数类型给自己的变量赋值}public T getOb() {return ob;}}
?
实例264 泛型类的类型识别示例
//泛型运行时类型识别 1public class GenericRTTI {public static void main(String args[]) {MyFirstGeneric<Double> dou = new MyFirstGeneric<Double>(100.0);MyFirstGeneric<String> str = new MyFirstGeneric<String>("hellow");if (dou instanceof MyFirstGeneric)//判断dou是否是MyFirstGeneric类的实例System.out.println("MyFirstGeneric<Integer> object is instance of MyFirstGeneric");if (dou instanceof MyFirstGeneric<?>)//判断dou是否是MyFirstGeneric<?>泛型类的实例System.out.println("MyFirstGeneric<Integer> object is instance of MyFirstGeneric<?>");if (dou.getClass() == str.getClass())//判断这两个对象运行时的类是否相等System.out.println("MyFirstGeneric<Integer> class equals MyFirstGeneric<String> class");}}
?
实例265 强制类型转换示例
//强制类型转换public class CastType {public static void main(String args[]) {Father<Double> father = new Father<Double>(1.0);Child<Double, String> child = new Child<Double, String>(200.0, "中国您好");// 试图将子类对象转换成父类,正确if ((Father<Double>) child instanceof Father)System.out.println("子类对象转换成父亲对象.");// 试图将父类对象转换成子类,错误try {if ((Child<Double, String>) father instanceof Child)System.out.println("父类对象转换成子亲对象.");} catch (Exception e) {System.out.println(e);System.out.println("发生异常的原因:父类对象不能强制转换成子亲对象.");}}}
?
14.3 擦拭
实例266 无限界的擦拭
import java.util.Date;//有限界的擦拭public class BorderWipe<T extends Date> {// 下面所有的T将被String所代替T date;BorderWipe(T date) {this.date = date;}T getOb() {return date;}}
?
实例267 有限界的擦拭
//无限界的擦拭public class UnBorderWipe<T> {// 下面所有的T将被Object所代替T ob;UnBorderWipe(T ob) {this.ob = ob;}T getOb() {return ob;}}
?
14.4 集合泛型类
实例268 Hashtable的泛型化
import java.util.Hashtable;//Hashtable的泛型化public class HashtableGeneric<K, V> {// 创建Hashtable的泛型类对象public Hashtable<K, V> hashTable = new Hashtable<K, V>();// 创建put方法为key和value赋值public void put(K k, V v) {hashTable.put(k, v);}// 创建get方法可以根据key值获取value的值public V get(K k) {return hashTable.get(k);}public static void main(String args[]) {HashtableGeneric<String, String> t = new HashtableGeneric<String, String>();t.put("key", "Java语言");String s = t.get("key");System.out.println("根据key值获取的value的内容:\n\t" + s);}}
?
实例269 多功能画笔
import java.awt.*;import java.awt.event.*;import java.util.*;//多功能画笔public class Paintbrush extends Frame{private final static int POINT = 0;private final static int LINE = 1;private final static int RECTANGLE = 2;private final static int OVAL = 3;private int type; // 画笔类型Point p1;Point p2;ArrayList<Point> points = new ArrayList<Point>();ArrayList<DrawPoint> area = new ArrayList<DrawPoint>();public Paintbrush(String s) {super(s);}public void mainFrame() {MenuBar menuBar = new MenuBar();Menu menu = new Menu("菜单");MenuItem fmi4 = new MenuItem("Exit");fmi4.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.exit(0);}});menu.addSeparator();menu.add(fmi4);Menu mtype = new Menu("画笔种类");MenuItem menuItem = new MenuItem("点状");menuItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {type = Paintbrush.POINT;}});MenuItem menuItem2 = new MenuItem("线状");menuItem2.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {type = Paintbrush.LINE;}});MenuItem dmi3 = new MenuItem("矩形");dmi3.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {type = Paintbrush.RECTANGLE;}});MenuItem dmi4 = new MenuItem("圆形");dmi4.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {type = Paintbrush.OVAL;}});mtype.add(menuItem);mtype.add(menuItem2);mtype.add(dmi3);mtype.add(dmi4);menuBar.add(menu);menuBar.add(mtype);setMenuBar(menuBar);addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});addMouseListener(new MouseAdapter() {public void mousePressed(MouseEvent e) {p1 = new Point(e.getX(), e.getY());if (type == Paintbrush.POINT) {points.add(p1);repaint();}}public void mouseReleased(MouseEvent e) {if (type != Paintbrush.POINT) {p2 = new Point(e.getX(), e.getY());area.add(new DrawPoint(p1, p2, type));repaint();}}});setBounds(50, 50, 640, 480);setBackground(Color.WHITE);setVisible(true);}public void paint(Graphics g) {Iterator<Point> ip = points.iterator(); // 使用泛型g.setColor(Color.black);while (ip.hasNext()) {Point p = ip.next(); // 使用泛型g.fillOval(p.x, p.y, 10, 10);}// 起始点坐标int x1, y1, x2, y2;for (Iterator<DrawPoint> ipp = area.iterator(); ipp.hasNext();) {DrawPoint pp = ipp.next();x1 = (int) pp.startPoint.getX();y1 = (int) pp.startPoint.getY();x2 = (int) pp.endPoint.getX();y2 = (int) pp.endPoint.getY();switch (pp.type) {case LINE:g.setColor(Color.green);g.drawLine(x1, y1, x2, y2);break;case RECTANGLE:g.setColor(Color.red);g.drawRect(x1, y1, x2 - x1, y2 - y1);// 鼠标从右向左或从下往上拖动,不能绘制出图像:负值无意义break;case OVAL:g.setColor(Color.blue);g.drawOval(x1, y1, x2 - x1, y2 - y1);break;default:break;}}}public static void main(String[] args) {Paintbrush drawApp = new Paintbrush("多功能彩色画笔");drawApp.mainFrame();}}class DrawPoint {public Point startPoint;public Point endPoint;public int type;public DrawPoint(Point sPoint, Point ePoint, int drawType) {startPoint = sPoint;endPoint = ePoint;type = drawType;}}
?