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& ...
随机推荐
- 简单的XMPP服务器与客户端交互
由客户端发起 C: <stream:stream to="localhost" xmlns="jabber:client" xmlns:stream=&q ...
- 北航软院2015级C#期末考试部分考题讲解
洗洗睡了吧,我怎么知道明天的考试题目! 或者 你明年补考可以过来看看:) 晚安.
- [原创] Shell 参数传递 与 默认值
目录 简介 基本传参 $* 与 $@ 区别 默认参数(变量默认值) if 繁琐方式 - 变量为null = 变量为null时, 同时改变变量值 :- 变量为null 或 空字符串 := 变量为null ...
- SpringBoot入门(IDEA篇)(三)
一.什么是JPA JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate.TopLink等. 二.Mysql数据库示例 1.在app ...
- wordcloud词云--可视化
import jieba import wordcloud f = open("新时代中国特色社会主义.txt", "r", encoding="gb ...
- Python解释器的配置
1.准备工作 安装好Pycharm2017版本 电脑上安装好Python解释器 2.本地解释器配置 配置本地解释器的步骤相对简洁直观: (1)单击工具栏中的设置按钮. (2)在Settings/Pre ...
- Mac退出vim
按下ESC后输入:才能进入命令模式! 进入之后输入: qw (保存退出) 然后按2次大写Z退出 q! (不保存退出) 输入后回车退出
- post调试postman
载地址:https://www.getpostman.com/ 教程地址:http://www.cnblogs.com/s380774061/p/4624326.html
- web网站优化
没事儿研究一下YAHOO工程师对网站优化给出的策略,对重点部分在这儿做下笔记 -----------------------------------------------我是分割线--------- ...
- es第十篇:Elasticsearch for Apache Hadoop
es for apache hadoop(elasticsearch-hadoop.jar)允许hadoop作业(mapreduce.hive.pig.cascading.spark)与es交互. A ...