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& ...
随机推荐
- “全栈2019”Java第四十八章:重写方法Override
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- easy-ui grid里的toobar按钮隐藏与显示
//隐藏第一个按钮$('div.datagrid-toolbar a').eq(0).hide();//隐藏第一条分隔线$('div.datagrid-toolbar div').eq(0).hide ...
- js 常用js正则表达式大全
一.校验数字的js正则表达式 1 数字:^[0-9]*$ 2 n位的数字:^d{n}$ 3 至少n位的数字:^d{n,}$ 4 m-n位的数字:^d{m,n}$ 5 ...
- 基础篇:6.5)形位公差-基本规则 Basic Rules
本章目的:述说形位公差的基本规则 1.代表规则的修正符号与使用情况: 使用情况举例: 2 有关术语 为了明确线性尺寸公差与形位公差之间关系,对尺寸术语将作进一步论述与定义. //无需强记,但希望现有 ...
- 高阶篇:4.2.3)DFMEA现有设计:预防控制与探测控制
本章目的:在现有设计中,明确预防控制与探测控制的定义和手段. 1.现有控制的填写部位: 2.现行设计控制(h)定义: 作为设计过程的一部分,现行设计控制是已经实施或承诺的活动,它将确保设计充分考虑设计 ...
- Angular material mat-icon 资源参考_Warning
ul,li>ol { margin-bottom: 0 } dt { font-weight: 700 } dd { margin: 0 1.5em 1.5em } img { height: ...
- PIE SDK 距离分类和最大似然分类
1.算法功能简介 监督分类,也叫训练场地法.训练分类法,是遥感图像分类的一种,用被确认类别的样本像元去识别其他未知类别像元的过程.监督分类算法有平行算法.平行六面体法.最小距离法.最大似然法.马 ...
- linux 安装谷歌浏览器
1. 下载 rpm 包https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm2. 安装依赖包yum ins ...
- c# 闲谈异常处理
今天在阅读 .net 源码时发现微软对所有使用枚举类型的地方对枚举值进行了检测,在检测不通过时抛出了异常. , )) { throw new InvalidEnumArgumentException( ...
- 在vue中import()语法不能传入变量
解决办法: 一定要用变量的时候,可以通过字符串模板来提供部分信息给webpack:例如import(`./path/${myFile}`), 这样编译时会编译所有./path下的模块,但运行时确定my ...