Java基础之泛型——使用二叉树进行排序(TryBinaryTree)
控制台程序。
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)的更多相关文章
- 黑马程序员:Java基础总结----泛型(高级)
黑马程序员:Java基础总结 泛型(高级) ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 泛型(高级) 泛型是提供给javac编译器使用的,可以限定集合中的输入类型 ...
- Java基础总结--泛型总结
-----泛型------JDK1.5出现的机制1.泛型出现的原因--简化书写,提高安全性技术的由来是为了解决问题,现在存在该问题,所有的容器定义类型为Object,所以任何对 象均可以放入容器--进 ...
- 黑马程序员——JAVA基础之泛型和通配符
------- android培训.java培训.期待与您交流! ---------- 泛型: JDK1.5版本以后出现新特性.用于解决安全问题,是一个类型安全机制. 泛型好处: ...
- Java基础知识--泛型
什么是泛型?为什么使用泛型? 泛型,就是参数化类型.提到参数,最熟悉的就是定义方法时候的形参,然后调用此方法时传递实参.顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也 ...
- Java基础知识强化58:经典排序之二叉树排序(BinaryTreeSort)
1. 二叉树排序 二叉树排序的描述也是一个递归的描述, 所以二叉树排序的构造自然也用递归的: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它 ...
- 黑马程序员——【Java基础】——泛型、Utilities工具类、其他对象API
---------- android培训.java培训.期待与您交流! ---------- 一.泛型 (一)泛型概述 1.泛型:JDK1.5版本以后出现的新特性,用于解决安全问题,是一个类型安全机制 ...
- Java基础:泛型
Java的泛型是什么呢, 就是类型的參数化,这得类型包含方法參数和返回值.也就是原本该是确定类型的地方换成了变量,把类型的确定时间向后延迟了. 在之前,学过"重载"的概念,重载是什 ...
- 【Java基础】泛型
Num1:请不要在新代码中使用原生类型 泛型类和接口统称为泛型.每种泛型定义一组参数化的类型,构成格式是:类或接口名称,接着用<>把对应于泛型形式类型的参数的实际参数列表括起来.比如:Li ...
- java基础之 泛型
泛型(Generic type 或者generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法 ...
随机推荐
- jquery格式化时间戳 2011-01-01
/* * 时间戳转换日期 * @param <int> unixTime 待时间戳(秒) ...
- directX基础学习系列7 网格(自己创建)
D3DXMesh 以及 D3DXPMesh都是从ID3DXBaseMesh类中集成,mesh基本是对三角单元进行操作 ID3DXBaseMesh主要函数: HRESULT DrawSubset( DW ...
- nginx服务器调优
nginx服务器调优措施总结: 1.选择合适的网络IO模型 epoll select poll 2.配置合适的启动进程数和每个进程处理请求的工作线程数 3.启用gzip压缩以减小通信量以减少网络IO ...
- BS架构与CS架构的区别(最全)
C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境的优势. ...
- Locking
Computer Science An Overview _J. Glenn Brookshear _11th Edition To solve such problems, a DBMS could ...
- hiho42 : 骨牌覆盖问题·二
描述 上一周我们研究了2xN的骨牌问题,这一周我们不妨加大一下难度,研究一下3xN的骨牌问题?所以我们的题目是:对于3xN的棋盘,使用1x2的骨牌去覆盖一共有多少种不同的覆盖方法呢?首先我们可以肯定, ...
- jboss4.2.3建立oracle JMS应用
一.基本配置 1 增加oracle驱动文件,ojdbc6.jar,不能使用小于该版本的jdbc驱动,jboss-4.2.3.GA\server\default\lib 2 增加retrotransla ...
- nodejs express测试
1.页面请求 app.get('/list_user', function (req, res) { console.log("/list_user GET 请求"); //res ...
- 大数据情况下linux的配置
一:配置的大纲 主要的配置有几个方面: 主机名 IP 网络映射 增加新用户 给新用户root的权限,方便实验 关闭防火墙 安全子系统需要关闭 二:主机名的配置 命令:vi /etc/sysconfig ...
- Asp.net Session保存到Redis: 使用 RedisSessionStateProvider
Install-Package Microsoft.Web.RedisSessionStateProvider 依赖于: Dependencies StackExchange.Redis.Strong ...