控制台程序。
1、实现针对容器类的基于集合的循环
为了让容器类类型的对象能够在基于集合的for循环中可用,类必须并且只需要满足一个要求——必须实现泛型接口java.lang.Iterable<>。接口Iterable<T>是声明了单个方法iterable<T>接口并且提供对iterable()方法的实现。
1 import java.util.Iterator; 2 3 public class LinkedList<T> implements Iterable<T> { 4 5 // Returns an iterator for this list 6 public Iterator<T> iterator() { 7 return new ListIterator(); // Create iterator of the inner class type 8 } 9 10 // Default constructor - creates an empty list 11 public LinkedList() {} 12 13 // Constructor to create a list containing one object 14 public LinkedList(T item) { 15 if(item != null) { 16 current = end = start = new ListItem(item); // item is the start and end 17 } 18 } 19 20 // Construct a linked list from an array of objects 21 public LinkedList(T[] items) { 22 if(items != null) { 23 // Add the items to the list 24 for(int i = 0; i < items.length; ++i) { 25 addItem(items[i]); 26 } 27 current = start; 28 } 29 } 30 31 // Add an item object to the list 32 public void addItem(T item) { 33 ListItem newEnd = new ListItem(item); // Create a new ListItem 34 if(start == null) { // Is the list empty? 35 start = end = newEnd; // Yes, so new element is start and end 36 } else { // No, so append new element 37 end.next = newEnd; // Set next variable for old end 38 end = newEnd; // Store new item as end 39 } 40 } 41 // Get the first object in the list 42 public T getFirst() { 43 current = start; 44 return start == null ? null : start.item; 45 } 46 47 // Get the next object in the list 48 public T getNext() { 49 if(current != null) { 50 current = current.next; // Get the reference to the next item 51 } 52 return current == null ? null : current.item; 53 } 54 55 private ListItem start = null; // First ListItem in the list 56 private ListItem end = null; // Last ListItem in the list 57 private ListItem current = null; // The current item for iterating 58 59 private class ListItem { 60 61 // Constructor 62 public ListItem(T item) { 63 this.item = item; // Store the item 64 next = null; // Set next as end point 65 } 66 67 // Return class name & object 68 @Override 69 public String toString() { 70 return "ListItem " + item ; 71 } 72 73 ListItem next; // Refers to next item in the list 74 T item; // The item for this ListItem 75 } 76 77 private class ListIterator implements Iterator<T> { 78 // Constructor 79 public ListIterator() { 80 nextElement = getFirst(); 81 } 82 83 // Method to test whether more elements are available 84 public boolean hasNext() { 85 return nextElement != null; 86 } 87 88 // Method to return the next available object from the linked list 89 public T next() { 90 T element = nextElement; 91 if(element == null) { 92 throw new java.util.NoSuchElementException(); 93 } 94 nextElement = getNext(); 95 return element; 96 } 97 98 // Method to remove the last element retrieved from the linked list 99 // You don't want to support this operation for the linked list 100 // so just throw the exception 101 public void remove() { 102 throw new UnsupportedOperationException("Remove not supported for LinkedList<>"); 103 } 104 105 private T nextElement; 106 } 107 }
泛型LinkedList<>类类型现在实现了泛型接口类型Iterable<>,并且它们共享通用的类型参数。所以可以通过简单地实现Iterable<>接口并使用基于集合的for循环来定义包含任意类型对象集合的类,并且提供用于对内容进行迭代的功能。接口会自动被定制成能使用特定容器包含的任意类型对象。
2、定义二叉树泛型类
1 public class BinaryTree<T extends Comparable<T>> { 2 3 // Add a value to the tree 4 public void add(T value) { 5 if(root == null) { // If there's no root node 6 root = new Node(value); // store it in the root 7 } else { // Otherwise... 8 add(value, root); // add it recursively 9 } 10 } 11 12 // Recursive insertion of an object 13 private void add(T value, Node node) { 14 int comparison = node.obj.compareTo(value); 15 if(comparison == 0) { // If it is equal to the current node 16 ++node.count; // just increment the count 17 return; 18 } 19 if(comparison > 0) { // If it's less than the current node 20 if(node.left == null) { // and the left child node is null 21 node.left = new Node(value); // Store it as the left child node 22 } else { // Otherwise... 23 add(value, node.left); // ... call add() again at the left node 24 } 25 } else { // It must be greater than the current node 26 if(node.right == null) { // so it must go to the right... 27 node.right = new Node(value); // store it as the right node 28 } else { // ...or when right node is not null 29 add(value, node.right); // ...call add() again at the right node 30 } 31 } 32 } 33 34 // Create a list containing the values from the tree in sequence 35 public LinkedList<T> sort() { 36 LinkedList<T> values = new LinkedList<>(); // Create a linked list 37 treeSort(root, values); // Sort the objects into the list 38 return values; 39 } 40 41 // Extract the tree nodes in sequence 42 private void treeSort(Node node, LinkedList<T> values) { 43 if(node != null) { // If the current node isn't null 44 treeSort(node.left, values); // process its left child node 45 46 // List the duplicate objects for the current node 47 for(int i = 0 ; i < node.count ; ++i) { 48 values.addItem(node.obj); 49 } 50 treeSort(node.right, values); // Now process the right child node 51 } 52 } 53 54 private Node root; // The root node 55 56 // Private inner class defining nodes 57 private class Node { 58 Node(T value) { 59 obj = value; 60 count = 1; 61 } 62 63 T obj; // Object stored in the node 64 int count; // Count of identical objects 65 Node left; // The left child node 66 Node right; // The right child node 67 } 68 }
使用类型参数(用来约束参数化接口类型Comparable<T>的实现)来定义BinaryTree<T>。因此,使用BinaryTree<T>类型的任何类型参数都必须实现Comparable<T>接口。如果不这样做,代码就不会编译。这样可以确保添加到BinaryTree<T>对象的所有对象都有可用的Comparable()方法。
3、尝试使用BianaryTree<>对象对整数和字符串进行排序
1 public class TryBinaryTree { 2 public static void main(String[] args) { 3 int[] numbers = new int[30]; 4 for(int i = 0 ; i < numbers.length ; ++i) { 5 numbers[i] = (int)(1000.0*Math.random()); // Random integers 0 to 999 6 } 7 8 // List starting integer values 9 int count = 0; 10 System.out.println("Original values are:"); 11 for(int number : numbers) { 12 System.out.printf("%6d", number); 13 if(++count%6 == 0) { 14 System.out.println(); 15 } 16 } 17 18 // Create the tree and add the integers to it 19 BinaryTree<Integer> tree = new BinaryTree<>(); 20 for(int number:numbers) { 21 tree.add(number); 22 } 23 24 // Get sorted values 25 LinkedList<Integer> values = tree.sort(); 26 count = 0; 27 System.out.println(" Sorted values are:"); 28 for(Integer value : values) { 29 System.out.printf("%6d", value); 30 if(++count%6 == 0) { 31 System.out.println(); 32 } 33 } 34 35 // Create an array of words to be sorted 36 String[] words = {"vacillate", "procrastinate", "arboreal", "syzygy", 37 "xenocracy", "zygote" , "mephitic", "soporific", 38 "grisly" , "gristly" }; 39 40 // List the words 41 System.out.println(" Original word sequence:"); 42 for(String word : words) { 43 System.out.printf("%-15s", word); 44 if(++count%5 == 0) { 45 System.out.println(); 46 } 47 } 48 49 // Create the tree and insert the words 50 BinaryTree<String> cache = new BinaryTree<>(); 51 for(String word : words) { 52 cache.add(word); 53 } 54 55 // Sort the words 56 LinkedList<String> sortedWords = cache.sort(); 57 58 // List the sorted words 59 System.out.println(" Sorted word sequence:"); 60 count = 0; 61 for(String word : sortedWords) { 62 System.out.printf("%-15s", word); 63 if(++count%5 == 0) { 64 System.out.println(); 65 } 66 } 67 } 68 }
这里之所以能使用基于集合的for循环,是因为LinkedList<T>类型实现了Iterable<T>接口,这是让容器能使用这个for循环来访问元素的唯一先决条件。