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& ...
随机推荐
- 使用单个httpclient实例请求数据。
做J2EE的都知道httpclient这个工具,Android也自带这个工具,不过和J2EE上的不一样,可能是google在添加的时候,自己修改了一部分代码. 在J2EE中可以使用如下代码,在多线程的 ...
- [Python]json 错误xx is not JSON serializable
TypeError: Decimal('1457501') is not JSON serializable 在使用json的时候经常会遇到xxx is not JSON serializable, ...
- xcode - iPhone Debugging: How to resolve 'failed to get the task for process'? - Stack Overflow
The program being debugged is not being run. Everyone sees this once in a while during Xcode develop ...
- TX2之多线程读取视频及深度学习推理
背景 一般在TX2上部署深度学习模型时,都是读取摄像头视频或传入视频文件进行推理,从视频中抽取帧进行目标检测等任务.对于大点的模型,推理的速度是赶不上摄像头或视频的帧率的,如果我们使用单线程进行处理, ...
- python全栈开发_day8_文件的多种读写方式及游标
一:文件的多种读写方式 主方式:w r a 从方式:t b + 了解方式:x u 1)按t(按照字符进行操作): with open("data_1.txt& ...
- 基础篇:6.7)形位公差-检测方法Measurement
本章目的:了解行为公差的检测方法,简单评估公司和制作方的检测能力. 1.形位公差检测规定 形状和位置公差检测规定GB/T 1958 -2004 2.形位公差的种类 3.形位公差的测量仪器 人工测量仪器 ...
- PIE SDK组件式开发综合运用示例
1. 功能概述 关于PIE SDK的功能开发,在我们的博客上已经分门别类的进行了展示,点击PIESat博客就可以访问,为了初学者入门,本章节将对从PIE SDK组件式二次开发如何搭建界面.如何综合开发 ...
- ngx_echo_module
https://github.com/openresty/echo-nginx-module echo $echo_request_body
- reduce的用法
在不增加变量的情况下,统计数组中各元素出现的次数. ```jsfunction countItem (arr) { // 写入你的代码}countItem(['a', 'b', 'a', 'c', ' ...
- (转)MySQL性能调优my.cnf详解
MySQL性能调优my.cnf详解 https://blog.linuxeye.cn/379.html http://blog.csdn.net/orichisonic/article/details ...