- 浏览: 1688732 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (159)
- android 2D (13)
- android 控件 (12)
- android UI (16)
- android 动画 (5)
- android 线程 (3)
- android 数据存储 (15)
- android 基础 (13)
- android xml解析 (1)
- android 多媒体开发 (4)
- android 服务 (4)
- android 安全 (1)
- android WebKit以及相关 (3)
- android 电话 (2)
- android 首选项 (5)
- java基础 (16)
- java 多线程 (1)
- java IO (7)
- android工具使用篇 (1)
- android素材资源区 (1)
- android教程资源区 (1)
- java_android异常记录 (5)
- android问题记录 (1)
- android 推荐资源 (1)
- android 源码篇 (3)
- android SDK (2)
- Google Map For Android (2)
- android 项目问题 (2)
- git (0)
- android API 变化 (1)
- MyEclipse (2)
- Swing组件 (1)
- 活法 (0)
- 其它 (2)
- linux (7)
- 菜鸟的java学习笔记 (0)
- 网络 (0)
- 健康 (1)
- Eclipse在Ubuntu下无法双击启动解决办法 (1)
最新评论
-
tydyz:
引用
android SQLiteOpenHelper使用示例 -
tydyz:
[color=red][/color]
android SQLiteOpenHelper使用示例 -
tydyz:
[flash=200,200][flash=200,200][ ...
android SQLiteOpenHelper使用示例 -
梁家大丫头:
写的还不错,不过不是我需要的。
android 理解和使用自定义权限 -
love_java_cc:
牛逼,太齐全了,收藏
MyEclipse 快捷键大全
ThreeSet能够对集合中的对象排序,当TreeSet想集合中加入一个对象时,会把它插入到有序的对象序列中。那么TreeSet是如何排序呢?TreeSet支持两种排序方式:自然排序和客户化排序.在默认情况下TreeSet采用自然排序方式。
先来介绍介绍什么是自然排序吧
1、自然排序
在JDK类库中,有一部分类实现了Comparable接口,如Integer Double和String等。
Comparable接口有一个comparTo(Object o)方法,它返回整数类型。对于表达式x.compareTo(y),如果返回值为0,则表示x和y相等,如果返回值大于0,则表示x大于y,如果返回值小于0,则表示x小于y.TreeSet集合调用对象的compareTo()方法比较集合中的大小,注意鸟 不是TreeSet调用它自己的comparTo()方法而是它调用集合中对象的comparTo()方法.TreeSet类本身并没有实现Comparable接口,然后进行升序排列,这种方式称为自然排序.
有人可能要问TreeSet集合怎么给对象排序的按对象的什么排序的?
下面简单总结一哈
JDK类库中实现了Comparable接口的一些类的排序方式
这里一定要灰常注意:使用自然排序时只能向集合中加入同类型的对象,并且这些对象的类必须实现Comparable接口
下面来说说Comparable接口和Comparator接口的区别
Comparator位于包java.util下,而Comparable位于包 java.lang下
Comparable 是一个对象本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口) 此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
比如你有一个Customer类 想让这个类的实例加入集合后自动就具有某种排序功能只要这些实例加入集合后 就会按照你给Customer对象设定的方式排序
代码:
main方法的类
有人会问 重写hashCode()方法 equals方法干嘛 别急 慢慢道来
实际上,所有实现 Comparable 的 Java 核心类都具有与 equals 一致的自然排序。java.math.BigDecimal 是个例外,它的自然排序将值相等但精确度不同的 BigDecimal 对象(比如 4.0 和 4.00)视为相等。为了保证TreeSet能正确地排序,要求Customer类的compareTo()方法与equals()方法按相同的规则比较两个Customer对象是否相等.也就是说,如果customer1.equals(customer2)为True,那么customer1.compareTo(customer2)为0。 既然重写了equals方法 就得重写hashCode()方法这个大家都知道
大家看一眼结果便知 这个按照升序排序的 年龄也是按照升序
还有要注意哦,对于TreeSet中已经存在的Customer对象,如果修改了它们的name属性或age属性,则TreeSet不会对集合进行重新排序.例如下边的代码先把customer1和customer2 对象加入到TreeSet集合中,然后修改customer1的age属性
代码:
上边我先把
打印结果是:
然后我们把那句取消注释之后的打印结果是:
Tom 20如果按照升序应该在下边 但是却在上边 说明TreeSet没有给它重新排序哦在实际应用中Customer对象的name属性和age属性肯定应该是可以被修改的,因此不适合用TreeSet来排序。那大家也应该能想到最适合用TreeSet排序的就是不可变类了呗 比如Integer,Double,String等 所谓不可变类,是指当创建了这个类的实例后,就不允许修改它的属性值。大家以后用还是小心点好儿!
客户化排序
Comparator这个单词啥意思? 你知道不? 比较器的意思 学好英语还是挺好滴
除了自然排序,TreeSet还支持客户化排序.java.util.Comparator<Type>接口提供具体的排序方式,<Type>指定被比较的对象的类型,Comparator有个compar(Type x,Type y)方法,用于比较两个对象的大小,当compare(x,y)大于0时表示x大于y,小于0表示x小于y
等于0表示x等于y
来个例子如果希望TreeSet按照Customer对象的name属性进行降序排列,可以先创建一个实现Comparator接口的类
代码:
以上main方法在构造TreeSet的实例时,调用了它的TreeSet(Comparator comparator)构造方法.
TreeSet
public TreeSet(Comparator<? super E> comparator)构造一个新的空 TreeSet,它根据指定比较器进行排序。插入到该 set 的所有元素都必须能够由指定比较器进行相互比较:对于 set 中的任意两个元素 e1 和 e2,执行 comparator.compare(e1, e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set 中,则 add 调用将抛出 ClassCastException。
参数:
comparator - 将用来对此 set 进行排序的比较器。如果该参数为 null,则使用元素的自然顺序。
最后的打印结果是:
那你现在是不知道了comparable接口和comparable接口的区别了并且也能更好的使用TreeSet集合了
总结一下吧
单点解释吧:用自定义类实现Comparable接口,那么这个类就具有排序功能,Comparable和具体你要进行排序的类的实例邦定。而Comparator比较灵活,只需要通过构造方法指定一个比较器就行了实现它的自定义类仅仅定义了一种排序方式或排序规则。不言而喻,这种方式比较灵活。我们的要排序的类可以分别和多个实现Comparator接口的类绑定,从而达到可以按自己的意愿实现按多种方式排序的目的。Comparable——“静态绑定排序”,Comparator——“动态绑定排序”。
在多墨迹一点 说说编写java类时应该养成一些好习惯吧
一: 如果java类重新定义了equals方法,那么这个类也必须重新定义hashCode()方法,并且保证当两个对象用equals方法比较结果为true时,这两个对象的hashCode()方法的返回值相等.
二:如果java类实现了Comparable接口,那么这个类应该从新定义compareTo() equals() 和hashCode()方法,保证compareTo()和equals()方法采用相同的比较规则来比较两个对象是否相等,并且保证当两个对象用equals()方法比较的结果为true时,这两个对象的hashCode()方法的返回值相等.
HashSet和HashMap具有较好的性能,是Set和Map首选实现类,只有在需要排序的场合,才考虑使用TreeSet和TreeMap. LinkedList 和 ArrayList各有优缺点,如果经常对元素执行插入和删除操作,那么可以用LinkedList,如果经常随机访问元素,那么可以用ArrayList.
这里为什么是 result = 29 * result + age;
知道请回答
先来介绍介绍什么是自然排序吧
1、自然排序
在JDK类库中,有一部分类实现了Comparable接口,如Integer Double和String等。
Comparable接口有一个comparTo(Object o)方法,它返回整数类型。对于表达式x.compareTo(y),如果返回值为0,则表示x和y相等,如果返回值大于0,则表示x大于y,如果返回值小于0,则表示x小于y.TreeSet集合调用对象的compareTo()方法比较集合中的大小,注意鸟 不是TreeSet调用它自己的comparTo()方法而是它调用集合中对象的comparTo()方法.TreeSet类本身并没有实现Comparable接口,然后进行升序排列,这种方式称为自然排序.
有人可能要问TreeSet集合怎么给对象排序的按对象的什么排序的?
下面简单总结一哈
JDK类库中实现了Comparable接口的一些类的排序方式
类 BigDecimal BigInteger Byte Double Float Integer Long Short 排序方式是 | 按数字大小排序 |
类 Character是 | 按字符的Unicode值的数字大小排序 |
类 String是 | 按字符中字符的Unicode值排序 |
这里一定要灰常注意:使用自然排序时只能向集合中加入同类型的对象,并且这些对象的类必须实现Comparable接口
下面来说说Comparable接口和Comparator接口的区别
Comparator位于包java.util下,而Comparable位于包 java.lang下
Comparable 是一个对象本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口) 此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
比如你有一个Customer类 想让这个类的实例加入集合后自动就具有某种排序功能只要这些实例加入集合后 就会按照你给Customer对象设定的方式排序
代码:
package hang.jihe; import java.util.HashSet; import java.util.Set; public class Customer implements Comparable { private String name; private int age; public Customer(String name, int age) { this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Customer)) return false; final Customer other = (Customer) obj; if (this.name.equals(other.getName()) && this.age == other.getAge()) return true; else return false; } public static void main(String[] args) { Set<Customer> set = new HashSet<Customer>(); Customer customer1 = new Customer("Tom", 15); Customer customer2 = new Customer("Tom", 15); set.add(customer1); set.add(customer2); System.out.println(set.size()); } public int compareTo(Object o) { Customer other = (Customer) o; // 先按照name属性排序 if (this.name.compareTo(other.getName()) > 0) return 1; if (this.name.compareTo(other.getName()) < 0) return -1; // 在按照age属性排序 if (this.age > other.getAge()) return 1; if (this.age < other.getAge()) return -1; return 0; } @Override public int hashCode() { int result; result = (name == null ? 0 : name.hashCode()); result = 29 * result + age; return result; } }
main方法的类
package hang.jihe; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class CustomerTester { public static void main(String[] args) { Set<Customer> set = new TreeSet<Customer>(); set.add(new Customer("Tom",15)); set.add(new Customer("Tom",20)); set.add(new Customer("Tom",15)); set.add(new Customer("Mike",15)); Iterator<Customer> it = set.iterator(); while(it.hasNext()){ Customer customer = it.next(); System.out.println(customer.getName()+" "+customer.getAge()); } } }
//打印结果 Mike 15 Tom 15 Tom 20
有人会问 重写hashCode()方法 equals方法干嘛 别急 慢慢道来
实际上,所有实现 Comparable 的 Java 核心类都具有与 equals 一致的自然排序。java.math.BigDecimal 是个例外,它的自然排序将值相等但精确度不同的 BigDecimal 对象(比如 4.0 和 4.00)视为相等。为了保证TreeSet能正确地排序,要求Customer类的compareTo()方法与equals()方法按相同的规则比较两个Customer对象是否相等.也就是说,如果customer1.equals(customer2)为True,那么customer1.compareTo(customer2)为0。 既然重写了equals方法 就得重写hashCode()方法这个大家都知道
大家看一眼结果便知 这个按照升序排序的 年龄也是按照升序
还有要注意哦,对于TreeSet中已经存在的Customer对象,如果修改了它们的name属性或age属性,则TreeSet不会对集合进行重新排序.例如下边的代码先把customer1和customer2 对象加入到TreeSet集合中,然后修改customer1的age属性
代码:
package hang.jihe; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class TreeSetTest { public static void main(String[] args) { Set<Customer> set = new TreeSet<Customer>(); Customer customer1 = new Customer("Tom",15); Customer customer2 = new Customer("Tom",16); set.add(customer1); set.add(customer2); //customer1.setAge(20);//修改customer1实例的age Iterator<Customer> it=set.iterator(); while(it.hasNext()){ Customer customer=it.next(); System.out.println(customer.getName()+" "+customer.getAge()); } } }
上边我先把
customer1.setAge(20);这句注释掉
打印结果是:
Tom 15 Tom 16这个是我们要的结果 name 和age都是按照升序排序的
然后我们把那句取消注释之后的打印结果是:
Tom 20 Tom 16
Tom 20如果按照升序应该在下边 但是却在上边 说明TreeSet没有给它重新排序哦在实际应用中Customer对象的name属性和age属性肯定应该是可以被修改的,因此不适合用TreeSet来排序。那大家也应该能想到最适合用TreeSet排序的就是不可变类了呗 比如Integer,Double,String等 所谓不可变类,是指当创建了这个类的实例后,就不允许修改它的属性值。大家以后用还是小心点好儿!
客户化排序
Comparator这个单词啥意思? 你知道不? 比较器的意思 学好英语还是挺好滴
除了自然排序,TreeSet还支持客户化排序.java.util.Comparator<Type>接口提供具体的排序方式,<Type>指定被比较的对象的类型,Comparator有个compar(Type x,Type y)方法,用于比较两个对象的大小,当compare(x,y)大于0时表示x大于y,小于0表示x小于y
等于0表示x等于y
来个例子如果希望TreeSet按照Customer对象的name属性进行降序排列,可以先创建一个实现Comparator接口的类
代码:
package hang.jihe; import java.util.Comparator; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class CustomerComparator implements Comparator<Customer>{ public int compare(Customer c1, Customer c2) { if(c1.getName().compareTo(c2.getName())>0)return -1; if(c1.getName().compareTo(c2.getName())<0)return 1; return 0; } public static void main(String args[]){ Set<Customer> set = new TreeSet<Customer>(new CustomerComparator()); Customer customer1= new Customer("Tom",15); Customer customer3= new Customer("Jack",16); Customer customer2= new Customer("Mike",26); set.add(customer1); set.add(customer2); set.add(customer3); Iterator<Customer> it = set.iterator(); while(it.hasNext()){ Customer customer = it.next(); System.out.println(customer.getName()+" "+customer.getAge()); } } }
以上main方法在构造TreeSet的实例时,调用了它的TreeSet(Comparator comparator)构造方法.
Set<Customer> set = new TreeSet<Customer>(new CustomerComparator());这是干甚? 其实就是指定一个比较器 TreeSet集合里边的对象按照这个比较器的规则进行排序 我把TreeSet类的这个构造方法搞上来看看就明白了 TreeSet里边有这样一个构造方法
TreeSet
public TreeSet(Comparator<? super E> comparator)构造一个新的空 TreeSet,它根据指定比较器进行排序。插入到该 set 的所有元素都必须能够由指定比较器进行相互比较:对于 set 中的任意两个元素 e1 和 e2,执行 comparator.compare(e1, e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set 中,则 add 调用将抛出 ClassCastException。
参数:
comparator - 将用来对此 set 进行排序的比较器。如果该参数为 null,则使用元素的自然顺序。
最后的打印结果是:
Tom 15 Mike 26 Jack 16是倒序 ...
那你现在是不知道了comparable接口和comparable接口的区别了并且也能更好的使用TreeSet集合了
总结一下吧
单点解释吧:用自定义类实现Comparable接口,那么这个类就具有排序功能,Comparable和具体你要进行排序的类的实例邦定。而Comparator比较灵活,只需要通过构造方法指定一个比较器就行了实现它的自定义类仅仅定义了一种排序方式或排序规则。不言而喻,这种方式比较灵活。我们的要排序的类可以分别和多个实现Comparator接口的类绑定,从而达到可以按自己的意愿实现按多种方式排序的目的。Comparable——“静态绑定排序”,Comparator——“动态绑定排序”。
在多墨迹一点 说说编写java类时应该养成一些好习惯吧
一: 如果java类重新定义了equals方法,那么这个类也必须重新定义hashCode()方法,并且保证当两个对象用equals方法比较结果为true时,这两个对象的hashCode()方法的返回值相等.
二:如果java类实现了Comparable接口,那么这个类应该从新定义compareTo() equals() 和hashCode()方法,保证compareTo()和equals()方法采用相同的比较规则来比较两个对象是否相等,并且保证当两个对象用equals()方法比较的结果为true时,这两个对象的hashCode()方法的返回值相等.
HashSet和HashMap具有较好的性能,是Set和Map首选实现类,只有在需要排序的场合,才考虑使用TreeSet和TreeMap. LinkedList 和 ArrayList各有优缺点,如果经常对元素执行插入和删除操作,那么可以用LinkedList,如果经常随机访问元素,那么可以用ArrayList.
评论
2 楼
sunyao1000
2010-07-03
public int hashCode() { int result; result = (name == null ? 0 : name.hashCode()); result = 29 * result + age; return result; }
这里为什么是 result = 29 * result + age;
知道请回答
1 楼
suixinsuoyu12519
2010-06-29
很好 很详细
发表评论
-
java 反射api 学习
2011-11-24 15:32 2354觉得目前这很菜很菜的水平 熟悉 熟悉 API 会用就OK 了 ... -
Math Random ....
2011-11-19 22:00 3054Math.round是四舍五入函数。 Math.ran ... -
java 位运算 以及 相关 原码、反码、 补码 知识
2011-11-16 17:05 273我直接上链接吧,以后查找方便。 觉得还是有意义的. Jav ... -
java String 转换为 boolean
2011-11-04 10:11 6125two method 一:String s= ... -
openjdk 查看java 源码
2011-10-16 08:12 4174装了ubuntu 11.10 安装了 系统自带的默认 op ... -
64位 win7配置 JDK
2010-07-18 15:56 6457搞了一个 DELL studio 1458 笔记本。。 4 ... -
Object getClass()方法
2010-04-24 05:26 18498小菜总结到 大家都知道Object类有一个getCla ... -
找出数组中的重复元素不是集合哦
2010-04-21 06:48 4457先说说怎么找出两个数组中的重复元素,其实思路很简单 就是 ... -
教你简单理解冒泡排序
2010-04-21 05:16 1861上代码 package what; import jav ... -
数组的初始化
2010-04-21 04:36 2127数组被创建后,每个元素自动赋予其数据类型的默认值。另外,还 ... -
线程调度
2010-03-30 14:27 1888计算机通常只有一个CPU,在任意时刻只能一条机器指令, ... -
字符串倒序输出的两种方法
2010-03-08 14:14 4108题目:将字符串abcdefg倒序输出 方法一:利用Strin ... -
JAVA中String与StringBuffer的区别
2010-03-08 13:24 1290在java中有3个类来负责字符的操作。 1.Char ... -
java接口与抽象类的区别
2010-03-04 21:39 1913一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这 ... -
java中的接口和抽象类
2010-03-04 21:37 1845JAVA中的抽象类可以被继承 抽象类里边可以有普 ... -
java中静态代码块 静态方法 static
2010-03-04 15:17 4122java 静态代码块 静态方法区别 一般情况下,如果有些代码必 ...
相关推荐
【IT十八掌徐培成】Java基础第12天-02.TreeSet实现与Comparable接口.zip
介绍TreeSet集合用法,向TreeSet集合中添加类的对象,此类需实现Comparable接口,有实例,供需要的朋友下载学习。
图书馆管理 1.描述一个图书馆 2.进书,借书卡办理 3.借书,还书 4.查询某书的借出记录 5.查询借书卡的借出记录 6.显示图书列表(按借出次数排序)
TreeSet 是 Java 中的一个集合类,它实现了 SortedSet 接口,并且使用红黑树作为底层数据结构。TreeSet 具有以下主要特点: 排序性:TreeSet 中的元素是有序的,默认按照元素的自然顺序进行排序。或者,可以在创建 ...
使用TreeSet和Comparator,编写TreeSetTest2类,要求对TreeSet中的元素1-元素10进行排列,排序逻辑为奇数在前偶数在后,奇数按照升序排列,偶数按照降序排列。 如果需要的话可以下载,有写成文章的。有写了一点中文...
什么是 Comparable 和 Comparator 接口?它们有什么区别? 如何使用 ConcurrentHashMap 类来实现线程安全的映射? 如何避免在多线程环境下对同一集合的并发修改? 如何使用 PriorityQueue 类实现一个最小堆? 如何...
这是为了方便大家了解集合类的相关知识所找的一个MarkDown文档,读者可以通过阅读了解各种子类集合的实现原理,红黑树的实现也会有所介绍.
Set接口的实现类包括HashSet、LinkedHashSet和TreeSet。 HashSet是基于哈希表实现的Set集合,它不保证集合中元素的顺序。由于哈希表的实现机制,HashSet的添加、删除和查找操作都具有很好的性能,时间复杂度为O(1)。...
哈希值 LinkedHashSet TreeSet 自然排序Comparable 比较器排序Comparator Set集合 并发修改异常 LinkedList集合 ArrayList集合 List集合 Collection集合概述 冒泡排序 Object 异常 Math 包装类 Calendar类 ...
java集合在日常开发中经常用到,对基础的掌握尤其重要,其中List,Set,Map的作用以及使用的场景和分类描述,其中Arraylist 与 LinkedList 区别,HashSet与TreeSet与LinkedHashSet对⽐,LinkedHashMap和HashMap,...
定制排序:在创建TreeSet集合对象时,并提供一个Comparator接口实现类对象与该TreeSet集合关联, 由Comparator实现类对象负责集合元素的排序逻辑。 // 自定义比较器 class MyTreeSetCompartor implements...
毕向东Java基础视频教程-集合框架(TreeSet练习).
day18-集合-中(HashSet&TreeSet&比较器).zip
Comparator<String> com = new Comparator<String>(){ public int compare(String o1,String o2) { return o1.length()-o2.length(); } }; TreeSet ts = new TreeSet(com); ts.add("string"); ts.add(...
NULL 博文链接:https://elvin-chu.iteye.com/blog/1942033
List接口、ArrayList类、Vector类、栈操作类Stack、链表操作类LinkList、队列操作接口Queue、Set接口、HashSet类、TreeSet类、SortedSet接口 双值操作接口Map(key->value)及其子接口、子类: SortedMap接口、HashMap...
java提供了一个Comparable接口,该接口里定义了一个compareTo(Objectobj)方法,该方法返回一个整数值,实现该接口的类必须实现该方法,实现了该接口的类的对象就可以比较大小。当一个对象调用该方法与另一个对象进行...
主要介绍了详解Java中HashSet和TreeSet的区别的相关资料,需要的朋友可以参考下
HashSet和TreeSet_围墙之外.rar
* 元素由它们的⾃然 Comparable 排序,或者通过⼀个由顺序 set 创建时特别提供的 * Comparator。这个 set 的迭代器将会以递增元素顺序横穿 set。提供多个额外的操作来⽀持排 * 序。(这个接⼝与 SortedMap 的 set ...