控制台程序
定义Point类:
1 public class Point { 2 // Create a point from its coordinates 3 public Point(double xVal, double yVal) { 4 x = xVal; 5 y = yVal; 6 } 7 8 // Create a point from another point 9 public Point(Point point) { 10 x = point.x; 11 y = point.y; 12 } 13 14 // Convert a point to a string 15 @Override 16 public String toString() { 17 return x+","+y; 18 } 19 20 // Coordinates of the point 21 protected double x; 22 protected double y; 23 }
定义泛型类LinkedList<T>:
1 public class LinkedList<T> { 2 // Default constructor - creates an empty list 3 public LinkedList() {} 4 5 // Constructor to create a list containing one object 6 public LinkedList(T item) { 7 if(item != null) { 8 current = end = start = new ListItem(item); // item is the start and end 9 } 10 } 11 12 // Construct a linked list from an array of objects 13 public LinkedList(T[] items) { 14 if(items != null) { 15 // Add the items to the list 16 for(int i = 0; i < items.length; ++i) { 17 addItem(items[i]); 18 } 19 current = start; 20 } 21 } 22 23 // Add an item object to the list 24 public void addItem(T item) { 25 ListItem newEnd = new ListItem(item); // Create a new ListItem 26 if(start == null) { // Is the list empty? 27 start = end = newEnd; // Yes, so new element is start and end 28 } else { // No, so append new element 29 end.next = newEnd; // Set next variable for old end 30 end = newEnd; // Store new item as end 31 } 32 } 33 // Get the first object in the list 34 public T getFirst() { 35 current = start; 36 return start == null ? null : start.item; 37 } 38 39 // Get the next object in the list 40 public T getNext() { 41 if(current != null) { 42 current = current.next; // Get the reference to the next item 43 } 44 return current == null ? null : current.item; 45 } 46 47 private ListItem start = null; // First ListItem in the list 48 private ListItem end = null; // Last ListItem in the list 49 private ListItem current = null; // The current item for iterating 50 51 private class ListItem { 52 53 // Constructor 54 public ListItem(T item) { 55 this.item = item; // Store the item 56 next = null; // Set next as end point 57 } 58 59 // Return class name & object 60 @Override 61 public String toString() { 62 return "ListItem " + item ; 63 } 64 65 ListItem next; // Refers to next item in the list 66 T item; // The item for this ListItem 67 } 68 }
使用LinkedList<T>泛型类的PolyLine类:
1 public class PolyLine { 2 // Construct a polyline from an array of coordinate pairs 3 public PolyLine(double[][] coords) { 4 Point[] points = new Point[coords.length]; // Array to hold points 5 6 // Create points from the coordinates 7 for(int i = 0; i < coords.length ; ++i) { 8 points[i] = new Point(coords[i][0], coords[i][1]); 9 } 10 11 // Create the polyline from the array of points 12 polyline = new LinkedList<>(points); // Create list of Point objects 13 } 14 15 // Construct a polyline from an array of points 16 public PolyLine(Point[] points) { 17 polyline = new LinkedList<>(points); // Create list of Point objects 18 } 19 20 // Add a Point object to the list 21 public void addPoint(Point point) { 22 polyline.addItem(point); // Add the point to the list 23 } 24 25 // Add a point from a coordinate pair to the list 26 public void addPoint(double x, double y) { 27 polyline.addItem(new Point(x, y)); // Add the point to the list 28 } 29 30 // String representation of a polyline 31 @Override 32 public String toString() { 33 StringBuffer str = new StringBuffer("Polyline:"); 34 Point point = polyline.getFirst(); 35 // Set the 1st point as start 36 while(point != null) { 37 str.append(" ("+ point+ ")"); // Append the current point 38 point = polyline.getNext(); // Make the next point current 39 } 40 return str.toString(); 41 } 42 43 private LinkedList<Point> polyline; // The linked list of points 44 }
程序入口:
public class TryGenericLinkedList { public static void main(String[] args) { // Create an array of coordinate pairs double[][] coords = { {1, 1}, {1, 2}, { 2, 3}, {-3, 5}, {-5, 1}, {0, 0} }; // Create a polyline from the coordinates and display it PolyLine polygon = new PolyLine(coords); System.out.println(polygon); // Add a point and display the polyline again polygon.addPoint(10, 10); System.out.println(polygon); // Create Point objects from the coordinate array Point[] points = new Point[coords.length]; for(int i = 0; i < points.length; ++i) { points[i] = new Point(coords[i][0],coords[i][1]); } // Use the points to create a new polyline and display it PolyLine newPoly = new PolyLine(points); System.out.println(newPoly); } }
说明:
1、PolyLine类从LinkedList<T>泛型类中创建出LinkedList<Point>类型,从而实现了Point对象链表;
2、通过将Point作为类型变量T的参数传递到LinkedList<T>泛型类的定义中,可以生成相应的类类型。这个过程被称为类型擦除(Type erasure),因为出现类型变量T的所有位置都已经被Point替换。
3、在原始的泛型类定义中,类名之后出现的类型参数已经被移除,而且在类定义中出现T类型变量的位置都已被替换为Object类型。编译器之所以选择Object类型来替换类型变量,是因为Object类型是派生Point类型的最终超类。编译器选择的用于替换类型变量的类型是类型变量的最左边界。
4、设定类型参数的优势何在?毕竟使用Object类型作为参数能提供指向任意类型对象的引用。答案是:所提供的类型变量被编译器用来确保编译期间是类型安全的。在代码中使用LinkedList<Point>类型的对象时,编译器会检查使用它只是为了存储Point类型的对象,并且会将存储其它类型对象的任何企图都标记为错误。当调用LinkedList<Point>类型的对象的方法时,编译器会确保只提供Point类型的引用,其中原始的方法参数会被设定为类型参数。
5、定义和使用泛型类的本质内容其实很少。