如果加入TreeSet和TreeMap的元素没有实现comprable中的compareTo()方法,那么会报错“treeset cannot be cast to java.lang.Comparable”.

要解决这个问题有两种方法:

(1)让元素自身具有比较性;可以实现Comparable接口,实现compareTo()方法;

(2)让集合自身具有比较性;可以定义比较器,即让集合实现Comparator接口,然后实现compare()方法;

方法一:

因此需要对元素类型实现Comparable借口,并实现compareTo()方法,即告诉TreeSet和TreeMap你要怎么排列,它才能进行排序。

基础类:

package niukewang;

import java.util.Objects;

public class setClass implements Comparable<setClass>{

    String a;
String b;
public setClass(String a, String b)
{
this.a=a;
this.b=b;
} public int hashCode() {
return a.hashCode();
} public boolean equals(Object obj)
{
if(obj==null) return false; if(getClass() != obj.getClass()) return false; final setClass s=(setClass)obj; return Objects.equals(this.a, s.a);
} @Override
public int compareTo(setClass o) {
int num=this.b.compareTo(o.b);
return
num;
}
}

测试类:

package niukewang;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector; public class test1 { public static void main(String args[])
{
setClass s1=new setClass("http://www.yjbys.com/", "same0");
setClass s2=new setClass("http://www.yjbys.com1/", "same0");
setClass s3=new setClass("http://www.yjbys.com2/", "same2");
setClass s4=new setClass("http://www.yjbys.com2/", "same3"); //hasSet
System.out.println("hasSet......");
Set<setClass> set=new HashSet<setClass>();
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
Iterator it= set.iterator();
while(it.hasNext())
{
setClass ob=(setClass)it.next();
System.out.println(ob.a);
} //TreeSet
System.out.println("\nTreeSet........");
Set<setClass> tree=new TreeSet<setClass>();
tree.add(s1);
tree.add(s2);
tree.add(s3);
tree.add(s4);
Iterator treeit=tree.iterator();
while(treeit.hasNext())
{
setClass ob=(setClass) treeit.next();
System.out.println(ob.a);
}
//TreeMap
System.out.println("\nTreeMap.........");
Map<setClass,String> treemap=new TreeMap<setClass,String>();
treemap.put(s1, "TreeMap one");
treemap.put(s2, "TreeMap two");
treemap.put(s3, "TreeMap three");
treemap.put(s4, "TreeMap four");
for(Map.Entry<setClass, String> entry: treemap.entrySet())
{
System.out.println("The treemap key is "+entry.getKey().a+" The value is "+ entry.getValue());
} //HasMap
System.out.println("\nHashMap......");
Map<setClass,String> hashmap=new HashMap<setClass, String>();
hashmap.put(s1, "HashMap one");
hashmap.put(s2, "HashMap two");
hashmap.put(s3, "HashMap three");
hashmap.put(s4, "HashMap four");
for(Map.Entry<setClass, String> entry : hashmap.entrySet())
{
System.out.println("The key is "+entry.getKey().a+" The value is "+entry.getValue());
} //HasTable
System.out.println("\nHashTable......");
Map<setClass,String> hashtable=new Hashtable<setClass, String>();
hashtable.put(s1, "HashTable one");
hashtable.put(s2, "HashTable two");
hashtable.put(s3, "HashTable three");
hashtable.put(s4, "HashTable four");
for(Map.Entry<setClass, String> entry: hashtable.entrySet())
{
System.out.println("The HashTable key is "+entry.getKey().a+" The HashTable value is "+entry.getValue());
} //LinkedList
System.out.println("\nLinkedList.....");
List list=new LinkedList();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
Iterator listit=list.iterator();
while(listit.hasNext())
{
setClass ob=(setClass)listit.next();
System.out.println(ob.a);
} //ArrayList
System.out.println("\nArrayList.....");
List array=new ArrayList();
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
Iterator arrayit=array.iterator();
while(arrayit.hasNext())
{
setClass ob=(setClass)arrayit.next();
System.out.println(ob.a);
} //vector
System.out.println("\nvector.....");
Vector v=new Vector();
v.add(s1);
v.add(s2);
v.add(s3);
v.add(s4);
Iterator vit=v.iterator();
while(vit.hasNext())
{
setClass ob=(setClass)vit.next();
System.out.println(ob.a);
} }
}

输出结果:

hasSet......
http://www.yjbys.com1/
http://www.yjbys.com/
http://www.yjbys.com2/

TreeSet........
http://www.yjbys.com/
http://www.yjbys.com2/
http://www.yjbys.com2/
TreeMap.........
The treemap key is http://www.yjbys.com/ The value is TreeMap two
The treemap key is http://www.yjbys.com2/ The value is TreeMap three
The treemap key is http://www.yjbys.com2/ The value is TreeMap four HashMap......
The key is http://www.yjbys.com1/ The value is HashMap two
The key is http://www.yjbys.com/ The value is HashMap one
The key is http://www.yjbys.com2/ The value is HashMap four HashTable......
The HashTable key is http://www.yjbys.com1/ The HashTable value is HashTable two
The HashTable key is http://www.yjbys.com/ The HashTable value is HashTable one
The HashTable key is http://www.yjbys.com2/ The HashTable value is HashTable four LinkedList.....
http://www.yjbys.com/
http://www.yjbys.com1/
http://www.yjbys.com2/
http://www.yjbys.com2/ ArrayList.....
http://www.yjbys.com/
http://www.yjbys.com1/
http://www.yjbys.com2/
http://www.yjbys.com2/ vector.....
http://www.yjbys.com/
http://www.yjbys.com1/
http://www.yjbys.com2/
http://www.yjbys.com2/

TreeSet并不像hashSet那样,用hashCode和equals取决于元素是否相等。
而是取决于compareTo()方法中指定的排序的方式;

setClass s1=new setClass("http://www.yjbys.com/", "same0");
  setClass s2=new setClass("http://www.yjbys.com1/", "same0");
  setClass s3=new setClass("http://www.yjbys.com2/", "same2");
  setClass s4=new setClass("http://www.yjbys.com2/", "same3");

如果用hashCode和equals取决于元素是否相等,那么s3和s4是相等的;

而此时候,是根据compareTo()方法中的第二个字符串b来判断是否相等,则s1与s2相等,s3和s4不相等,所以才有这样的输出:

TreeSet........
http://www.yjbys.com/
http://www.yjbys.com2/
http://www.yjbys.com2/

方法二:

定义比较器,让集合实现Comparator接口,然后实现compare方法,则集合自身具有比较性。

其中Class Student 是实现了Comparable接口的,是元素本身具有比较性,在main方法中添加到TreeSet中的时候,能体现出来,通过年龄来比较大小;如果年龄和姓名相同,则是完全相等;

其中成员方法testComparator()中,定义了一个TreeSet,使其实现Comparator接口,并实现了方法compare(),通过setClass类中的a的属性的大小;因此此方法中的TreeSet具有比较性;

package niukewang;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet; import org.junit.Test; //非线程安全
public class TreeSetTest {
/**
* TreeSet:它可以给Set集合中的元素进行指定方式的排序。 保证元素唯一性的方式:通过比较的结果是否为0. 底层数据结构是:二叉树。
*
* 排序的第一种方式: 让元素自身具备比较性。只要让元素实现Comparable接口,覆盖compareTo方法即可。
*
* 但是,如果元素自身不具备比较性,或者元素自身具备的比较性,不是所需要的。
* 比如,学生的自然排序是按年龄排序,现在想要按照学生姓名排序。还可以不改动原有代码。 这时怎么办呢?
*
* 排序的第二种方式:自定比较器的方式。这时可以让集合自身具备比较性。
*
* 可以定义一个类实现Comparator接口,覆盖compare方法。
* 将该Comparator接口子类对象作为实际参数传递给TreeSet集合构造函数。
*/
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
// Student如果不实现Comparable,add时会出错,Student cannot be cast to java.lang.Comparable
//添加第一个对象时,TreeSet里没有任何元素,所以没有问题;
//当添加第二个Err对象时,TreeSet就会调用该对象的compareTo(Object obj)方法与集合中其他元素进行比较——
//如果对应的类没有实现Comparable接口,则会引发ClassCastException异常
// add方法内部会对插入的数据进行排序,此时元素自身具备比较性,因为其实现了Comparable接口
ts.add(new Student("lisi0", 30));
ts.add(new Student("lisixx", 29));
ts.add(new Student("lisi9", 29));
ts.add(new Student("lisi8", 38));
// 重复插入无效,但是不报错(根据年龄和名字进行比较,都相同,视为同一个学生)
ts.add(new Student("lisixx", 29));
ts.add(new Student("lisixx", 28));
ts.add(new Student("lisi4", 14));
ts.add(new Student("lisi7", 27));
System.out.println(ts); System.out.println("testComparator........\n");
TreeSetTest ob=new TreeSetTest();
ob.testComprator();
} //自定义比较器,让集合自身具备比较性
@Test
public void testComprator()
{
setClass s1=new setClass("http://www.yjbys.com/", "same0");
setClass s2=new setClass("http://www.yjbys.com1/", "same0");
setClass s3=new setClass("http://www.yjbys.com2/", "same2");
setClass s4=new setClass("http://www.yjbys.com2/", "same3"); Set<setClass> treeset=new TreeSet<setClass>(new Comparator<setClass>(){ @Override
public int compare(setClass arg0, setClass arg1) {
// TODO Auto-generated method stub
int num=arg0.a.compareTo(arg1.a); //只比较属性a的大小
return num;
}
}); treeset.add(s1);
treeset.add(s2);
treeset.add(s3);
treeset.add(s4); System.out.println(treeset);
} //同姓名同年龄的学生视为同一个学生
public static class Student implements Comparable<Student> { private int age;
private String name; public Student(String name, int age) {
this.age = age;
this.name = name;
} @Override
public int compareTo(Student stu) {
int num = new Integer(this.age).compareTo(new Integer(stu.age));
return num == 0 ? this.name.compareTo(stu.name) : num;
} public String toString() {
return name + "::" + age;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
}

运行结果:

[lisi4::14, lisi7::27, lisixx::28, lisi9::29, lisixx::29, lisi0::30, lisi8::38]
testComparator........ [http://www.yjbys.com/ :: same0, http://www.yjbys.com1/ :: same0, http://www.yjbys.com2/ :: same2]

由上图可知:
Stuent类是通过年龄判断的,所以按年龄排序;只有姓名和年龄都相同时,则认为是相同的,所以ts.add(new Student("lisixx", 29))不会重复添加;其他因为姓名不同,就算年龄相同,也认为是不相同的;

setClass类,是根据setClass中的属性a的值是否相等,就算hashCode和equals方法被重写了,它只看比较性。

注意:

如果在setClass类中,如果没有重写public String toString()方法,则会输出类似下面的输出:

[niukewang.setClass@cbf33da, niukewang.setClass@8b2747d3, niukewang.setClass@8b2747f2]

但是如果重写了public String toString()方法:

public String toString()
 {
  return this.a+" :: "+this.b;
 }

则会输出:[http://www.yjbys.com/ :: same0, http://www.yjbys.com1/ :: same0, http://www.yjbys.com2/ :: same2]

TreeSet和TreeMap的输出的更多相关文章

  1. TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树

    TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树   本文链接:https://blog.csdn.net/u010698072/article/de ...

  2. Java 集合类 TreeSet、TreeMap

    TreeMap和TreeSet的异同: 相同点: TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是拍好序的. TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之 ...

  3. 第40讲:Set、Map、TreeSet、TreeMap操作代码实战

    今天来看下set map的操作,让我们从代码出发 val data = mutable.Set.empty[Int] data ++= List(1,2,3)//在空set上加入列表 data += ...

  4. TreeSet与TreeMap浅解

    TreeSet与TreeMap的关系: 1.TreeSet 实际上就是用TreeMap来组织数据的,因为在TreeSet中保存了一个NavigableMap<e,Object>接口实例变量 ...

  5. Java容器-引用数据类型排序+TreeSet、TreeMap底层实现

    目录 1.冒泡排序的实现 2.比较接口(普通数据类型.引用数据类型) 普通数据类型:冒泡排序 引用数据类型:包装类(Integer.String.Character.Date) 自定义类型:实体类:i ...

  6. B树和TreeSet与TreeMap

    1. 此前二叉搜索树相关的内容我们均假设可以把整个数据结构存储在计算机的内存中,但是如果数据量过大时,必须把数据结构放在磁盘上,导致大O模型不在适用.目前计算机处理器每秒至少可以执行5亿条指令,磁盘访 ...

  7. JDK学习---深入理解Comparator、TreeSet、TreeMap为什么可以排序

    我本来打算仔细的去分析分析TreeSet和TreeMap排序规则,并且从底层实现和数据结构入手.当我去读完底层源码以后,我感觉我就的目标定的太大了,单单就是数据结构就够我自己写很久了,因此我决定先易后 ...

  8. TreeSet和TreeMap中“相等”元素可能并不相等

    TreeSet和TreeMap元素之间比较大小是借助Comparator对象的compare方法. 但有些时候,即便compare()返回0也不意味着这两个元素直观上相同. 比如元素是二元组[a,b] ...

  9. 零基础学习java------day15--------collections用法,比较器,Set(TreeSet,TreeMap),异常

    1. Collections用法 Collections: 集合的工具类public static <T> void sort(List<T> list) 排序,升序publi ...

随机推荐

  1. UVALive 6663 Count the Regions --离散化+DFS染色

    题意:给你n(n<=50)个矩形(左上角坐标和右下角坐标),问这些矩形总共将平面分成多少个部分.坐标值可能有1e9. 分析:看到n和坐标的范围,容易想到离散化,当时就没想到离散化以后怎么判断区域 ...

  2. XUtils===XUtils3框架的基本使用方法

    转载自:http://blog.csdn.NET/a1002450926/article/details/50341173 今天给大家带来XUtils3的基本介绍,本文章的案例都是基于XUtils3的 ...

  3. Unity原厂讲师大解密

    Asset Bundle工作流程及人物换装实例- 刘刚 Unity内部的资源有两种 Resources:有10年历史,尽量用资产包 Asset Bundle:昵称AB,现今Unity处理资源的中心 A ...

  4. Apache Shiro权限框架在SpringMVC+Hibernate中的应用

    在做网站开发中,用户权限必须要考虑的,权限这个东西很重要,它规定了用户在使用中能进行哪 些操作,和不能进行哪些操作:我们完全可以使用过滤器来进行权限的操作,但是有了权限框架之后,使用起来会非常的方便, ...

  5. Java虚拟机工作原理详解 ( 二 )

    首先这里澄清两个概念:JVM实例和JVM执行引擎实例,JVM实例对应了一个独立运行的Java程序,而JVM执行引擎实例则对应了属于用户运行程序的线程:也就是JVM实例是进程级别,而执行引擎是线程级别的 ...

  6. 看ImplicitBackwardEulerSparse关于static solve的代码

    当选择static solve的时候,求解的流程如下: 1.获得内力 2.qresidual = 外力-内力,qdelta = qresidual, qdelta的非约束元素赋给bufferConst ...

  7. 【转】【WPF】WPF 自定义快捷键命令(Command)

    命令简介 WPF 中的命令是通过实现 ICommand 接口创建的.ICommand 公开两个方法(Execute 及 CanExecute)和一个事件(CanExecuteChanged).Exec ...

  8. 处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表

    IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决办法 IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Int ...

  9. JS案例之6——瀑布流布局(1)

    在实际的项目中,偶尔会用到一种布局——瀑布流布局.瀑布流布局的特点是,在多列布局时,可以保证内容区块在水平方向上不产生大的空隙,类似瀑布的效果.简单的说,在垂直列表里,内容区块是一个挨着一个的.当内容 ...

  10. 数据摘要算法的测试效率(SHA、MD5和CRC32)

    1.算法概述 数据摘要算法是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名.数据完整性校验等功能,由于其不可逆性,有时候会被用做敏感信息的加密.数据摘要算法也被称为哈希(H ...