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));
}
}
}
}
编译运行后输出:
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为什么可以实现自动排序?的更多相关文章
- Java基础教程:对象比较排序
Java基础教程:对象比较排序 转载请标明出处:http://blog.csdn.net/wangtaocsdn/article/details/71500500 有时候需要对对象列表或数组进行排序, ...
- 禁用datagridview中的自动排序功能
把datagridview中的自动排序功能禁用自己收集的两种方法,看看吧①DataGridView中的Columns属性里面可以设置.进入"EditColumns"窗口后,在相应的 ...
- sublime插件 cssComb实现css自动排序及格式化
cssComb是一个实现css代码自动排序,当然顺便也实现了代码的格式化 安装: 首先需要打开sublime搜索安装csscomb插件(前提是已经安装了sublime的package control) ...
- DataGridView点击排序完成后如何禁止自动排序
Summary: Disable sorting after clicking DataGridView columnheader,Prevent databound DataGridView fro ...
- Java比较器对数组,集合排序一
数组排序非常简单,有前辈们的各种排序算法,再加上Java中强大的数组辅助类Arrays与集合辅助类Collections,使得排序变得非常简单,如果说结合比较器Comparator接口和Collato ...
- java结构与算法之选择排序
一 .java结构与算法之选择排序(冒择路兮快归堆) 什么事选择排序:从一组无序数据中选择出中小的的值,将该值与无序区的最左边的的值进行交换. 简单的解释:假设有这样一组数据 12,4,23,5,找到 ...
- 我们一起来排序——使用Java语言优雅地实现常用排序算法
破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...
- yii去掉自动排序功能
Yii去掉自动排序功能并自定义排序 public function search($params) { $query = SvnManage::find()->addOrderBy([ 'cre ...
- C++的STL之map自动排序特性
#include <iostream> #include <map> using namespace std; int main() {方法一: map<int,int& ...
随机推荐
- 一个标准的AJAX请求
这是一个标准的ajax请求: $.ajax({ type:"post", url:basePath+"/resourcePush/operationLog", ...
- Python 验证码识别(别干坏事哦...)
关于python验证码识别库,网上主要介绍的为pytesser及pytesseract,其实pytesser的安装有一点点麻烦,所以这里我不考虑,直接使用后一种库. python验证码识别库安装 要安 ...
- CRC循环冗余校验算法
现实中通信链路都不会是理想的,比特在传输的过程中可能会出现差错,0变成1,1变成0.这就叫做比特差错.因此为了保证数据传输的可靠性,在计算网络传输数据时,必须采用各种检验措施来处理比特差错.在数据链路 ...
- Access MongoDB Data with Entity Framework 6
This article shows how to access MongoDB data using an Entity Framework code-first approach. Entity ...
- 分享VMware题目解答
VMnet1是主机模式.是一个Host-Only网络模式 192.168.1.254/24VMnet8是NAT模式.是一个NAT方式,最简单的组网方式VMnet6是手动设置的(主机.net.内部) 1 ...
- K2路由器刷机笔记
临近双11,K2路由器广告加的越来越放肆,实在太难忍受就刷了个固件.这里把路由器刷机的一般流程记录一下. 一.开启telnet 刷固件,首先要取得路由器系统的控制权,这样我们才能自由的进行操作. 方法 ...
- Linux 内存监控
1.按照内存使用方式排序 top 之后使用 shift + m 那么top按照内存使用从大到小进行排列,使用 shift + P 表示按照CPU进行排序. bigfish 1118m 438m 30m ...
- java中的Lamdba表达式和Stream
基于JDK 1.8 1.循环: // 以前的循环方式 for (String player : players) { System.out.print(player + "; ") ...
- 高阶篇:4.1)QFD质量功能展开-总章
本章目的:了解QFD概念和作用,为FMEA打下基础. 1.QFD定义 质量功能展开QFD(Quality Function Deployment),是把顾客或市场的要求转化为设计要求.零部件特性.工艺 ...
- 【Python】端口扫描脚本
0x00 使用模块简介 1.optparse模块 选项分析器,可用来生成脚本使用说明文档,基本使用如下: import optparse #程序使用说明 usage="%prog -H ...