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));
     }
   }
 }
}

编译运行后输出:

12
23
39
45
JACK
KING
SUN
TOM
2003-04-12
2003-08-12
2004-09-17
2013-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.6
4.0
3.7
3.6
3.4 wx搜索“程序员考拉”,专注java领域,一个伴你成长的公众号!

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

  1. Java基础教程:对象比较排序

    Java基础教程:对象比较排序 转载请标明出处:http://blog.csdn.net/wangtaocsdn/article/details/71500500 有时候需要对对象列表或数组进行排序, ...

  2. 禁用datagridview中的自动排序功能

    把datagridview中的自动排序功能禁用自己收集的两种方法,看看吧①DataGridView中的Columns属性里面可以设置.进入"EditColumns"窗口后,在相应的 ...

  3. sublime插件 cssComb实现css自动排序及格式化

    cssComb是一个实现css代码自动排序,当然顺便也实现了代码的格式化 安装: 首先需要打开sublime搜索安装csscomb插件(前提是已经安装了sublime的package control) ...

  4. DataGridView点击排序完成后如何禁止自动排序

    Summary: Disable sorting after clicking DataGridView columnheader,Prevent databound DataGridView fro ...

  5. Java比较器对数组,集合排序一

    数组排序非常简单,有前辈们的各种排序算法,再加上Java中强大的数组辅助类Arrays与集合辅助类Collections,使得排序变得非常简单,如果说结合比较器Comparator接口和Collato ...

  6. java结构与算法之选择排序

    一 .java结构与算法之选择排序(冒择路兮快归堆) 什么事选择排序:从一组无序数据中选择出中小的的值,将该值与无序区的最左边的的值进行交换. 简单的解释:假设有这样一组数据 12,4,23,5,找到 ...

  7. 我们一起来排序——使用Java语言优雅地实现常用排序算法

    破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...

  8. yii去掉自动排序功能

    Yii去掉自动排序功能并自定义排序 public function search($params) { $query = SvnManage::find()->addOrderBy([ 'cre ...

  9. C++的STL之map自动排序特性

    #include <iostream> #include <map> using namespace std; int main() {方法一: map<int,int& ...

随机推荐

  1. go语言实战教程:Redis实战项目应用

    项目Redis配置 在实战项目中使用Redis功能,首先需要进行Redis配置.本实战项目中,关与Redis的配置项包含:连接类型.地址.端口.公共前缀.以上配置项被定义包含在Iris框架的redis ...

  2. [agc016b]Colorful Hats 分类讨论

    Description ​ 有n个人,每个人都戴着一顶帽子.当然,帽子有不同的颜色. ​ 现在,每个人都告诉你,他看到的所有其他人的帽子共有多少种颜色,请问你有没有符合所有人的描述的情况. Input ...

  3. 洛谷P4220 [WC2018]通道(边分治+虚树)

    题面 传送门 题解 代码不就百来行么也不算很长丫 虽然这题随机化贪心就可以过而且速度和正解差不多不过我们还是要好好学正解 前置芝士 边分治 米娜应该都知道点分治是个什么东西,而边分治,顾名思义就是对边 ...

  4. 洛谷P5050 【模板】多项式多点求值

    传送门 人傻常数大.jpg 因为求逆的时候没清零结果调了几个小时-- 前置芝士 多项式除法,多项式求逆 什么?你不会?左转你谷模板区,包教包会 题解 首先我们要知道一个结论\[f(x_0)\equiv ...

  5. 生产环境elasticsearch

    生产环境建议用curl来调用elasticsearch的restful接口来创建索引,每个索引的index脚本,mapping的脚本都提前写好提到git上打包,部署的时候直接通过curl执行 开发环境 ...

  6. React-Native 工程添加推送功能 (iOS 篇)

    推送已经是是手机应用的基本功能,如果自己实现一套推送系统费时费力,所有一般我们会使用第三方的推送服务,这里我使用「极光推送」作为集成推送的例子,因为有现成的 react native 插件 jpush ...

  7. Unity---解决重新调整游戏分辨率后,再运行游戏还是和之前分辨率一样的问题

    经历 上次在Unity做了个小游戏,发布的时候忘了取消默认全屏了. 于是在Unity重新发布了一下,可是出来后分辨率还是默认全屏. 当时百思不得其解 原因 主要是因为当用Unity发布一个新游戏的时候 ...

  8. Cache缓存设计

    缓存的适用场景: 缓存的目的是提高访问速度,减少不必要的开销,提高性能.那什么样的场景适用于缓存呢.试想一个多项式的计算是一个CPU bound的操作,如果频繁调用同一个多项式的结果.显然缓存结果是一 ...

  9. pip安装python库总是超时或出错的解决办法

    建个文件 ~/.pip/pip.conf, 内容如下 [global] timeout = index-url = http://pypi.douban.com/simple/ [install] u ...

  10. 基础篇:3)规范化:3d制图总章

    本章目的:明确3d绘图也有相应的准则,遵守者方有相应的进阶之路. 1.建模目标:拥有自己的建模思想 学习完成3d制图,最直接的评价标准就是--拥有自己的建模思想. 其表现为: 1)建模思路明确,能独立 ...