天天看点

【ThinkingInJava】50、使用特定的set

/**
* 书本:《Thinking In Java》
* 功能:使用特定的set
* 文件:TypesForSets.java
* 时间:2015年5月2日11:05:43
* 作者:cutter_point
*/
package Lesson17Containers;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

class SetType
{
	int i;
	public SetType(int n) { i = n; }
	public boolean equals(Object o)
	{
		//首先判定进来比较的是不是SetType这个类型,然后比较里面的值是不是一样的
		return o instanceof SetType && (i == ((SetType)o).i);
	}
	
	public String toString()
	{
		return Integer.toString(i);	//返回i的字符串显示
	}
}

class HashType extends SetType
{
	//这里注意,如果继承的类里面有构造函数,那么继承的子类也必须有构造函数初始化父类
	public HashType(int n)
	{
		super(n);
	}
	
	public int hashCode() { return i; }
}

class TreeType extends SetType implements Comparable<TreeType>
{
	public TreeType(int n)
	{
		super(n);
	}
	
	public int compareTo(TreeType arg)		//实现Comparable接口
	{
		//arg的成员变量i不是私有的,所以可以直接取出来
		//如果参数比成员元素大那就返回-1
		//比成员元素小,返回1
		//如果相等那就返回0
		return (arg.i < i ? -1 : (arg.i == i ? 0 : 1));	//treeSet的排序应该是-1排前面去,1排后面去
	}
}


public class TypesForSets
{
	//以set集合和一个Class为参数,对set进行填充
	static <T> Set<T> fill(Set<T> set, Class<T> type)
	{
		try
		{
			for(int i = 0; i < 10; ++i)	//给set添加10个实例
				set.add(type.getConstructor(int.class).newInstance(i));	//首先得到构造器,然后传入一个int类型的参数,然后实例化
		} 
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
		return set;
	}
	
	static <T> void test(Set<T> set, Class<T> type)
	{
		TypesForSets.fill(set, type);
		TypesForSets.fill(set, type);
		TypesForSets.fill(set, type);		//添加多次一样的数据和添加一次的结果是相同的
		System.out.println(set);
	}

	public static void main(String[] args)
	{
		test(new HashSet<HashType>(), HashType.class);	//以一个神秘的次序排列
		test(new LinkedHashSet<HashType>(), HashType.class);	//以插入的循序排列
	    test(new TreeSet<TreeType>(), TreeType.class);	//以compareTo的次序排列,这里是倒序
	    // Things that don't work:	//但是当没有实现hashCode 而是用默认的话,那么set就会失去去除重复的功能
	    test(new HashSet<SetType>(), SetType.class);
	    test(new HashSet<TreeType>(), TreeType.class);
	    test(new LinkedHashSet<SetType>(), SetType.class);
	    test(new LinkedHashSet<TreeType>(), TreeType.class);
	    try
	    {
	    	test(new TreeSet<HashType>(), HashType.class);
	    }
	    catch(Exception e)
	    {
	    	System.out.println(e.getMessage());
	    }
	}

}
           

输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

[1, 1, 8, 4, 9, 0, 0, 2, 3, 9, 6, 7, 8, 4, 7, 3, 2, 5, 3, 7, 9, 4, 0, 5, 2, 1, 5, 6, 8, 6]

[2, 6, 0, 7, 9, 7, 5, 2, 6, 2, 7, 3, 4, 8, 1, 6, 4, 1, 3, 3, 8, 5, 9, 8, 0, 1, 9, 0, 5, 4]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

java.lang.ClassCastException: Lesson17Containers.HashType cannot be cast to java.lang.Comparable