控制台程序。

1、实现针对容器类的基于集合的循环

为了让容器类类型的对象能够在基于集合的for循环中可用,类必须并且只需要满足一个要求——必须实现泛型接口java.lang.Iterable<>。接口Iterable<T>是声明了单个方法iterable<T>接口并且提供对iterable()方法的实现。

 import java.util.Iterator;

 public class LinkedList<T> implements Iterable<T> {

   // Returns an iterator for this list
public Iterator<T> iterator() {
return new ListIterator(); // Create iterator of the inner class type
} // Default constructor - creates an empty list
public LinkedList() {} // Constructor to create a list containing one object
public LinkedList(T item) {
if(item != null) {
current = end = start = new ListItem(item); // item is the start and end
}
} // Construct a linked list from an array of objects
public LinkedList(T[] items) {
if(items != null) {
// Add the items to the list
for(int i = 0; i < items.length; ++i) {
addItem(items[i]);
}
current = start;
}
} // Add an item object to the list
public void addItem(T item) {
ListItem newEnd = new ListItem(item); // Create a new ListItem
if(start == null) { // Is the list empty?
start = end = newEnd; // Yes, so new element is start and end
} else { // No, so append new element
end.next = newEnd; // Set next variable for old end
end = newEnd; // Store new item as end
}
}
// Get the first object in the list
public T getFirst() {
current = start;
return start == null ? null : start.item;
} // Get the next object in the list
public T getNext() {
if(current != null) {
current = current.next; // Get the reference to the next item
}
return current == null ? null : current.item;
} private ListItem start = null; // First ListItem in the list
private ListItem end = null; // Last ListItem in the list
private ListItem current = null; // The current item for iterating private class ListItem { // Constructor
public ListItem(T item) {
this.item = item; // Store the item
next = null; // Set next as end point
} // Return class name & object
@Override
public String toString() {
return "ListItem " + item ;
} ListItem next; // Refers to next item in the list
T item; // The item for this ListItem
} private class ListIterator implements Iterator<T> {
// Constructor
public ListIterator() {
nextElement = getFirst();
} // Method to test whether more elements are available
public boolean hasNext() {
return nextElement != null;
} // Method to return the next available object from the linked list
public T next() {
T element = nextElement;
if(element == null) {
throw new java.util.NoSuchElementException();
}
nextElement = getNext();
return element;
} // Method to remove the last element retrieved from the linked list
// You don't want to support this operation for the linked list
// so just throw the exception
public void remove() {
throw new UnsupportedOperationException("Remove not supported for LinkedList<>");
} private T nextElement;
}
}

泛型LinkedList<>类类型现在实现了泛型接口类型Iterable<>,并且它们共享通用的类型参数。所以可以通过简单地实现Iterable<>接口并使用基于集合的for循环来定义包含任意类型对象集合的类,并且提供用于对内容进行迭代的功能。接口会自动被定制成能使用特定容器包含的任意类型对象。

2、定义二叉树泛型类

 public class BinaryTree<T extends Comparable<T>> {

   // Add a value to the tree
public void add(T value) {
if(root == null) { // If there's no root node
root = new Node(value); // store it in the root
} else { // Otherwise...
add(value, root); // add it recursively
}
} // Recursive insertion of an object
private void add(T value, Node node) {
int comparison = node.obj.compareTo(value);
if(comparison == 0) { // If it is equal to the current node
++node.count; // just increment the count
return;
}
if(comparison > 0) { // If it's less than the current node
if(node.left == null) { // and the left child node is null
node.left = new Node(value); // Store it as the left child node
} else { // Otherwise...
add(value, node.left); // ... call add() again at the left node
}
} else { // It must be greater than the current node
if(node.right == null) { // so it must go to the right...
node.right = new Node(value); // store it as the right node
} else { // ...or when right node is not null
add(value, node.right); // ...call add() again at the right node
}
}
} // Create a list containing the values from the tree in sequence
public LinkedList<T> sort() {
LinkedList<T> values = new LinkedList<>(); // Create a linked list
treeSort(root, values); // Sort the objects into the list
return values;
} // Extract the tree nodes in sequence
private void treeSort(Node node, LinkedList<T> values) {
if(node != null) { // If the current node isn't null
treeSort(node.left, values); // process its left child node // List the duplicate objects for the current node
for(int i = 0 ; i < node.count ; ++i) {
values.addItem(node.obj);
}
treeSort(node.right, values); // Now process the right child node
}
} private Node root; // The root node // Private inner class defining nodes
private class Node {
Node(T value) {
obj = value;
count = 1;
} T obj; // Object stored in the node
int count; // Count of identical objects
Node left; // The left child node
Node right; // The right child node
}
}

使用类型参数(用来约束参数化接口类型Comparable<T>的实现)来定义BinaryTree<T>。因此,使用BinaryTree<T>类型的任何类型参数都必须实现Comparable<T>接口。如果不这样做,代码就不会编译。这样可以确保添加到BinaryTree<T>对象的所有对象都有可用的Comparable()方法。

3、尝试使用BianaryTree<>对象对整数和字符串进行排序

 public class TryBinaryTree {
public static void main(String[] args) {
int[] numbers = new int[30];
for(int i = 0 ; i < numbers.length ; ++i) {
numbers[i] = (int)(1000.0*Math.random()); // Random integers 0 to 999
} // List starting integer values
int count = 0;
System.out.println("Original values are:");
for(int number : numbers) {
System.out.printf("%6d", number);
if(++count%6 == 0) {
System.out.println();
}
} // Create the tree and add the integers to it
BinaryTree<Integer> tree = new BinaryTree<>();
for(int number:numbers) {
tree.add(number);
} // Get sorted values
LinkedList<Integer> values = tree.sort();
count = 0;
System.out.println("\nSorted values are:");
for(Integer value : values) {
System.out.printf("%6d", value);
if(++count%6 == 0) {
System.out.println();
}
} // Create an array of words to be sorted
String[] words = {"vacillate", "procrastinate", "arboreal", "syzygy",
"xenocracy", "zygote" , "mephitic", "soporific",
"grisly" , "gristly" }; // List the words
System.out.println("\nOriginal word sequence:");
for(String word : words) {
System.out.printf("%-15s", word);
if(++count%5 == 0) {
System.out.println();
}
} // Create the tree and insert the words
BinaryTree<String> cache = new BinaryTree<>();
for(String word : words) {
cache.add(word);
} // Sort the words
LinkedList<String> sortedWords = cache.sort(); // List the sorted words
System.out.println("\nSorted word sequence:");
count = 0;
for(String word : sortedWords) {
System.out.printf("%-15s", word);
if(++count%5 == 0) {
System.out.println();
}
}
}
}

这里之所以能使用基于集合的for循环,是因为LinkedList<T>类型实现了Iterable<T>接口,这是让容器能使用这个for循环来访问元素的唯一先决条件。

Java基础之泛型——使用二叉树进行排序(TryBinaryTree)的更多相关文章

  1. 黑马程序员:Java基础总结----泛型(高级)

    黑马程序员:Java基础总结 泛型(高级)   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 泛型(高级) 泛型是提供给javac编译器使用的,可以限定集合中的输入类型 ...

  2. Java基础总结--泛型总结

    -----泛型------JDK1.5出现的机制1.泛型出现的原因--简化书写,提高安全性技术的由来是为了解决问题,现在存在该问题,所有的容器定义类型为Object,所以任何对 象均可以放入容器--进 ...

  3. 黑马程序员——JAVA基础之泛型和通配符

    ------- android培训.java培训.期待与您交流! ---------- 泛型:            JDK1.5版本以后出现新特性.用于解决安全问题,是一个类型安全机制. 泛型好处: ...

  4. Java基础知识--泛型

    什么是泛型?为什么使用泛型? 泛型,就是参数化类型.提到参数,最熟悉的就是定义方法时候的形参,然后调用此方法时传递实参.顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也 ...

  5. Java基础知识强化58:经典排序之二叉树排序(BinaryTreeSort)

    1. 二叉树排序 二叉树排序的描述也是一个递归的描述, 所以二叉树排序的构造自然也用递归的: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它 ...

  6. 黑马程序员——【Java基础】——泛型、Utilities工具类、其他对象API

    ---------- android培训.java培训.期待与您交流! ---------- 一.泛型 (一)泛型概述 1.泛型:JDK1.5版本以后出现的新特性,用于解决安全问题,是一个类型安全机制 ...

  7. Java基础:泛型

    Java的泛型是什么呢, 就是类型的參数化,这得类型包含方法參数和返回值.也就是原本该是确定类型的地方换成了变量,把类型的确定时间向后延迟了. 在之前,学过"重载"的概念,重载是什 ...

  8. 【Java基础】泛型

    Num1:请不要在新代码中使用原生类型 泛型类和接口统称为泛型.每种泛型定义一组参数化的类型,构成格式是:类或接口名称,接着用<>把对应于泛型形式类型的参数的实际参数列表括起来.比如:Li ...

  9. java基础之 泛型

    泛型(Generic type 或者generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法 ...

随机推荐

  1. 纸牌project

    用range[0,8)的列表表示牌,这些数字要出现两次.我们建议你通过连接两个range[0,8)的列表来创建这个list.利用Docs来安排列表串联操作 写一个draw handler啥样的draw ...

  2. Web Storage事件无法触发

    不管是在同源其他页面还是在本页面都不能触发storage事件. <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  3. C++ 读写文件流

    1. 读文件流  string readpro(const char* path) {   ifstream infile(path);   char buf[1024];   string mess ...

  4. Inno Setup入门(十)——操作注册表 & 自启程序

    http://379910987.blog.163.com/blog/static/3352379720110259414788/ 有些程序需要随系统启动,或者需要建立某些文件关联等问题,这些都是通过 ...

  5. UBUNTU 14.04 安装 OPENCV 2.4.9

    1.  从OpenCV.org 下载源代码 opencv-2.4.9.zip 2. 解压到准备好的目录 unzip opencv-2.4.9.zip 3. 进入源码目录,创建release目录 cd ...

  6. (转)js闭包初入门

    先看一段JS代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 function a(){             var num = 0;             function  ...

  7. SQL查询一周内过生日的用户

    SELECT birthday, )) + '-' + )) + '-' + )) AS datetime) AS Nbirthday FROM CRM_Customer WHERE birthday ...

  8. 大数据情况下linux的配置

    一:配置的大纲 主要的配置有几个方面: 主机名 IP 网络映射 增加新用户 给新用户root的权限,方便实验 关闭防火墙 安全子系统需要关闭 二:主机名的配置 命令:vi /etc/sysconfig ...

  9. [LeetCode] Decode Ways(DP)

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  10. Magento PDF发票,支持中文,以及修改的办法

    Magento PDF发票,支持中文,以及修改的办法.   如果让magento的PDF发票支持中文.Magento生成PDF发票.使用的是zend framework的zend_pdf类. 下面是一 ...