Java SortedSet为什么可以实现自动排序?

Set中的SortedSet(SortedSet为TreeSet的实现接口),它们之间的继承关系如下:

java.util.Set;

java.util.SortedSet;

java.util.TreeSet;

SortedSet中的元素无序不可重复,但是存进去的元素可以按照元素大小顺序自动排序。结合以下代码来看:

import java.util.*;import java.text.*;public class SortedSetTest01{ public static void main(String[] args)throws Exception{   SortedSet ss=new TreeSet();   //数字类   ss.add(12);   ss.add(23);   ss.add(45);   ss.add(39);   ss.add(45);   Iterator it=ss.iterator();   while(it.hasNext()){     System.out.println(it.next());   }   //String类   SortedSet str=new TreeSet();   str.add("JACK");   str.add("TOM");   str.add("KING");   str.add("SUN");   it=str.iterator();   while(it.hasNext()){     System.out.println(it.next());   }   //日期类   String st1="2003-08-12";   String st2="2004-09-17";   String st3="2003-04-12";   String st4="2013-09-04";      SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");   Date t1=sdf.parse(st1);   Date t2=sdf.parse(st2);   Date t3=sdf.parse(st3);   Date t4=sdf.parse(st4);      SortedSet times=new TreeSet();   times.add(t1);   times.add(t2);   times.add(t3);   times.add(t4);      it=times.iterator();   while(it.hasNext()){     Object element=it.next();     if(element instanceof Date){       Date d=(Date)element;       System.out.println(sdf.format(d));     }   } }}

编译运行后输出:

12233945JACKKINGSUNTOM2003-04-122003-08-122004-09-172013-09-04

以上代码展示了存在SortedSet中的元素可以按照元素大小进行排序,这些元素可以是数字类,字符串类或日期类等。既然知道了SortedSet的这一特性,那么SortedSet集合存储元素为什么可以自动排序?

在上面的代码中我们实现了SortedSet中的数字,字符串和日期类的自动排序,那么如果我们自定义几个User类型对象,然后把它们添加到SortedSet集合中去,可以实现像上面那样的自动排序吗?试一下。

import java.util.*;public class SortedSetTest02{ public static void main(String[] args){   SortedSet users=new TreeSet();   User u1=new User(12);   User u2=new User(16);   User u3=new User(23);   User u4=new User(32);   User u5=new User(43);      users.add(u1);   users.add(u2);   users.add(u3);   users.add(u4);   users.add(u5);   Iterator it=users.iterator();   while(it.hasNext()){     System.out.println(it.next());   } }}class User{ int age; User(int age){   this.age=age; } public String toString(){   return "User[age="+age+"]"; }}

编译通过,运行后出错,输出:

Exception in thread "main" java.lang.ClassCastException: User cannot be cast to java.lang.Comparable

at java.util.TreeMap.compare(Unknown Source)

at java.util.TreeMap.put(Unknown Source)

at java.util.TreeSet.add(Unknown Source)

at SortedSetTest02.main(SortedSetTest02.java:14)

User cannot be cast to java.lang.Comparable,也就是说User不可以转变成可比较的类型。所以User必须实现Comparable接口(也就是第一个程序例子中数字,字符串,日期底层已经实现了Comparable接口),即class User implements Comparable{ }。我们知道一个类实现一个接口就实现了这个接口的所有方法,SortedSet集合中的元素之所以可以自动排序,是因为使用add()方法添加进去的元素实现了Comparable接口中的CompareTo()方法。

上述代码中,如果我们给定一个需求,按照User的年龄排序,那么就需要编写一个比较规则,

public int compareTo(Object o){   //编写一个比较规则   int age1=this.age;   int age2=((User)o).age;   return age1-age2; }

compareTo的用法为u1.compareTo(u2),this为u1,括号里的参数o为u2,因为括号里的参数类型为Object类型,而Object类型没有age这个属性,所以必须把o强制类型转换为User类型,即(User)o。修改之后的整体代码如下:

import java.util.*;public class SortedSetTest02{ public static void main(String[] args){   SortedSet users=new TreeSet();   User u1=new User(12);   User u2=new User(16);   User u3=new User(23);   User u4=new User(32);   User u5=new User(43);      users.add(u1);   users.add(u2);   users.add(u3);   users.add(u4);   users.add(u5);   Iterator it=users.iterator();   while(it.hasNext()){     System.out.println(it.next());   } }}class User implements Comparable{ int age; User(int age){   this.age=age; } public String toString(){   return "User[age="+age+"]"; } //实现java.lang.Comparable;接口中的compareTo方法 //该方法程序员负责实现,SUN提供的程序已经调用了该方法 //需求:按照User的年龄排序 public int compareTo(Object o){  //u1.compareTo(u2)   //编写一个比较规则   int age1=this.age;      int age2=((User)o).age;   return age1-age2; }}

编译运行后输出:

User[age=12]User[age=16]User[age=23]User[age=32]User[age=43]

除此之外,还有另一种方法实现SortedSet集合排序:使用java.util.Comparator;来单独编写一个比较器,创建TreeSet集合的时候提供这个比较器,即SortedSet products=new TreeSet(new ProductComparator()); 代码如下:

import java.util.*;public class SortedSetTest03{ public static void main(String[] args){   //创建TreeSet集合的时候提供一个比较器   SortedSet products=new TreeSet(new ProductComparator());   Product p1=new Product(3.4);   Product p2=new Product(4.0);   Product p3=new Product(3.6);   Product p4=new Product(7.6);   Product p5=new Product(3.7);      products.add(p1);   products.add(p2);   products.add(p3);   products.add(p4);   products.add(p5);      Iterator it=products.iterator();   while(it.hasNext()){     System.out.println(it.next());     } }}class Product{ double price; Product(double price){   this.price=price; } public String toString(){   return price + ""; }}//单独编写一个比较器class ProductComparator implements Comparator{ //需求:按照商品价格排序 public int compare(Object o1,Object o2){   double price1=((Product)o1).price;   double price2=((Product)o2).price;   if (price1==price2){     return 0;   }else if(price1>price2){     return -1;   }   return 1; }}

编译运行后输出:

7.64.03.73.63.4

搜索微信公众号“程序员考拉”,欢迎关注!

原文地址:https://www.cnblogs.com/naihuangbao/p/9444481.html

时间: 2024-10-13 13:50:28

Java SortedSet为什么可以实现自动排序?的相关文章

TreeSet实现自动排序的原理

今天随手了一段代码关于通过treeSet实现自动排序的功能,自己折腾了好久. 始终是存在这一些疑惑,后来和同学的交流和调试可以解释自动排序的基本原理: 通过可以通过两种方式实现自动排序: 一种: package xyxysjxy.io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io

IOS数组自动排序

self.beacons = [beacons sortedArrayUsingComparator:^NSComparisonResult(BRTBeacon* obj1, BRTBeacon* obj2){ return obj1.distance.floatValue>obj2.distance.floatValue?NSOrderedDescending:NSOrderedAscending; }]; 数组的自动排序: 通过比较的方法进行   排序

使用CollectionViewSource,通过Xaml绑定自动排序

这个是一个完成分组和排序功能的Datagrid,同样只是简单的绑定到List集合,后台不用额外的代码,所有功能都在Xaml中完成: 首先在UI中定义CollectionViewSource资源,在这里定义排序和分组的规则 WPF中定义如下: 引入命名空间:xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" <Window.Resources> <CollectionViewSourc

Java几种常用的实现排序方法

import java.util.Random; public class NumberSort{ /** * 私有构造方法,禁止实例化 */ private NumberSort(){ super(); } /** * 冒泡排序 * 比较相邻的元素.如果第一个比第二个大,就叫唤他们两个位置. * 对每一组相邻的元素作同样的工作,从开始的第一对到结束后的最后一对,这样剩下的最后一个应该是最大的数. * 针对所有元素重复以上操作,除了最后一个. * 持续对越来越少的数进行以上的操作,直到没有任何一

[Java] HashMap、TreeMap、Hashtable排序

Java中对Map(HashMap,TreeMap,Hashtable等)的排序时间 首先简单说一下他们之间的区别: HashMap: 最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度.HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null.非 首先简单说一下他们之间的区别: HashMap: 最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度.HashMap

DBGrideh 实现自动排序

一.点击标题自动排序 1.在optioneh中设置:AutosortMarking:=True2.设置DbGridEh的属性:(不一定总要设置,与使用的数据连接有关)sortlocal:=True;3.uses 单元Ado------ehlibADoTclientData------ehlibCDSBDE ---------ehlibBDE EhLibUniDAC 4.Column属性 ColumDefValues->Title->TitleButton设为TRUE 二.+序列号

java结构与算法之选择排序

一 .java结构与算法之选择排序 什么事选择排序:从一组无序数据中选择出中小的的值,将该值与无序区的最左边的的值进行交换. 简单的解释:假设有这样一组数据 12,4,23,5,找到最小值 4 放在最右边,然后找到 5 放在  4 的后面,重复该操作. 选择排序参考代码: public class ChooseSort { int[] array = null; @Test public void testPopSort() { array = new int[5]; array[0] = 45

委托+拉姆达=自动排序(一)

我们总能看到和使用到根据字段排序的功能,也就是文件资源管理器中的点击自动排序的效果:             要实现这个功能首先必须在界面的html代码中进行如下设置: 即:为要排序的字段设置:sortable属性,也就是将该字段设置为可排序. 既然是界面的排序,就必须存在一个参数,向后台调取相应的方法返回数据到界面,那么方法有二: 1.将要排序的字段作为参数,层层传递,到后台调取方法: <span style="font-size:18px;"> //获取sort时,如果

map&lt;String ,String&gt; 自动排序 升序

//TreeMap自动排序 Map<String, String> params = new TreeMap<String, String>( new Comparator<String>() { public int compare(String obj1, String obj2) { // 升序排序 return obj1.compareTo(obj2); } });