我们知道TreeSet是Set接口下的一个实现类,TreeSet中的元素的排列顺序是和添加的顺序是没有关系的,并且它里面元素也是不能重复的
但是,TreeSet集合有它独有的特点,比如:
import java.util.*;
public class Test{
public static void main(String[] args){
TreeSet ts = new TreeSet();
ts.add("x");
ts.add("a");
ts.add("c");
ts.add("j");
System.out.println(ts);
}
}
看输出结果:
集合里元素的排序,虽然和你添加的顺序无关,但它会根据元素的unicode自然排序
但是,当你给集合中添加不同类型的数据时:
import java.util.*;
public class Test{
public static void main(String[] args){
TreeSet ts = new TreeSet();
ts.add("x");
ts.add("a");
ts.add("c");
ts.add(1);
System.out.println(ts);
}
}
出现的结果是:
就会报ClassCastException 类型转换异常
String 不能转成Integer类型,要排序,类型必须一致
说了这么多,TreeSet的排序好像就这么多了??
当然不是了,再往下看:
如果现在给集合里添加自定义类的对象怎么办?它又是怎么排序的呢?
import java.util.*;
class Person{
private String name ;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){
return "Person[name="+name+",age="+age+"]";
}
}
public class Test{
public static void main(String[] args){
TreeSet ts = new TreeSet();
ts.add(new Person("ab",20));
ts.add(new Person("ac",10));
ts.add(new Person("aa",20));
ts.add(new Person("ad",50));
System.out.println(ts);
}
}
再看运行结果:
可以看出,给出的异常信息是:Person类不能比较,为什么呢?
它给的异常信息指示是应该去实现Comparable接口,一般系统内置的类都已经实现了Comparable接口,像上面的String类,Integer类
不卖关子了,说一下,自定义类的对象作为TreeSet元素的两种方法排序:
第一种:让自定义的类实现Comparable接口,并实现里面的compareTo()抽象方法,此时自定义的类的对象就有了可比性
第二种:当自定义的类没有实现Comparable接口时,这时自定义的类的对象也就不具备可比性了,这时需要让集合自身具备可比性,在集合初始化时,可以指明集合的比较方式,即在new TreeSet()时,在里面写一个匿名内部类,该匿名内部类实现Comparator接口,再重写它的compare()方法,具体看代码
先看第一种:
看下面的代码,排序规则是自定义的,先按照年龄排序,在年龄相同的情况下,再按名字排序
import java.util.*;
class Person implements Comparable{
private String name ;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){
return "Person[name="+name+",age="+age+"]";
}
public int compareTo(Object obj){
if(!(obj instanceof Person)){
throw new ClassCastException("这不是人");
}
Person p = (Person)obj;
int n = this.age - p.age;
if(n == 0){
return this.name.compareTo(p.name);
}
return n;
}
}
public class Test{
public static void main(String[] args){
Set set = new TreeSet();
set.add(new Person("ab",20));
set.add(new Person("ac",10));
set.add(new Person("aa",20));
set.add(new Person("ad",50));
System.out.println(set);
}
}
看输出结果:
看中间两项,当年龄相同,都是20,此时,两者再按照名字排序
第二种:
此时,不实现Comparable接口,在new TreeSet()时,在里面写一个匿名内部类,该匿名内部类实现Comparator接口,再重写它的compare()方法
import java.util.*;
class Person{
private String name ;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){
return "Person[name="+name+",age="+age+"]";
}
public int getAge(){
return age;
}
public String getName(){
return name;
}
}
public class Test{
public static void main(String[] args){
Set set = new TreeSet(new Comparator(){
public int compare(Object obj1,Object obj2){
if(!((obj1 instanceof Person)&&(obj1 instanceof Person))){
throw new ClassCastException("这不是人");
}
Person p1 = (Person)obj1;
Person p2 = (Person)obj2;
System.out.println(p1 + "vs" + p2);
return p1.getAge()-p2.getAge();
}
});
set.add(new Person("ab",20));
set.add(new Person("ac",10));
set.add(new Person("aa",20));
System.out.println(set);
}
}
看输出结果:
最后一行是最终结果,前面三行是比较过程
这里只按照年龄排序,没有再按名字排序,所以最后输出的set只有两项,第三项和第一项重复,直接被过滤掉
注意一点,当两种方法都存在时,到底以哪种方法为主呢?
答案是,以第二种方法,以比较器comparator()为主
我们可以验证一下:看下面,把两个方法都放进去
import java.util.*;
class Person implements Comparable{
private String name ;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){
return "Person[name="+name+",age="+age+"]";
}
public int getAge(){
return age;
}
public String getName(){
return name;
}
public int compareTo(Object obj){
if(!(obj instanceof Person)){
throw new ClassCastException("这不是人");
}
Person p = (Person)obj;
int n = this.age - p.age;
if(n == 0){
return this.name.compareTo(p.name);
}
return n;
}
}
public class Test{
public static void main(String[] args){
Set set = new TreeSet(new Comparator(){
public int compare(Object obj1,Object obj2){
if(!((obj1 instanceof Person)&&(obj1 instanceof Person))){
throw new ClassCastException("这不是人");
}
Person p1 = (Person)obj1;
Person p2 = (Person)obj2;
return p1.getAge()-p2.getAge();
}
});
set.add(new Person("ab",20));
set.add(new Person("ac",10));
set.add(new Person("aa",20));
System.out.println(set);
}
}
如果输出的集合中有三项,则说明以第一种为主;
如果输出的集合中有两项,则说明以第二种为主
最终结果为:
输出的只有两项,说明了:当两种排序方式都存在时,以比较器为主
其实第一种方式是有安全隐患的,后续再来完善…..
<script type="text/javascript">
$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('<ul/>').addClass('pre-numbering').hide();
$(this).addClass('has-numbering').parent().append($numbering);
for (i = 1; i <= lines; i++) {
$numbering.append($('<li/>').text(i));
};
$numbering.fadeIn(1700);
});
});
</script>
版权声明:本文为博主原创文章,未经博主允许不得转载。
分享到:
相关推荐
Java SE程序 TreeSet类中自定义CompareTo类Java SE程序 TreeSet类中自定义CompareTo类Java SE程序 TreeSet类中自定义CompareTo类Java SE程序 TreeSet类中自定义CompareTo类Java SE程序 TreeSet类中自定义CompareTo类...
下面小编就为大家带来一篇浅谈TreeSet中的两种排序方式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
在TreeSet中添加自定义对象,能更好地帮助理解TreeSet
TreeSet支持两种排序方式: 自然排序:TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列。 定制排序:在创建TreeSet集合对象时,并提供一个Comparator接口...
·拒绝晦涩难懂的呆板教学,宋老师语言生动幽默,举例形象生动深入浅出,迅速让你把握问题本质,四两拨千斤 2.课程内容推陈出新: ·基于JDK 11,将Java8、Java9、Java10、Java11新特性一网打尽 ·课程中,Eclipse...
本文介绍TreeSet支持两种排序方法:自然排序和定制排序。TreeSet默认采用自然排序。详细请看下
使用TreeSet和Comparator,编写TreeSetTest2类,要求对TreeSet中的元素1-元素10进行排列,排序逻辑为奇数在前偶数在后,奇数按照升序排列,偶数按照降序排列。 如果需要的话可以下载,有写成文章的。有写了一点中文...
TreeSet 是 Java 中的一个集合类,它实现了 SortedSet 接口,并且使用红黑树作为底层数据结构。TreeSet 具有以下主要特点: 排序性:TreeSet 中的元素是有序的,默认按照元素的自然顺序进行排序。或者,可以在创建 ...
发布于2012-5-8TreeSet支持两种排序方法:自然排序和定制排序。TreeSet默认采用自然排序。TreeSet会调用集合元素的compareTo(Objectobj)方法来比较元素之间大小关系,然后将集合元素按升序排列,这种方式就是自然...
用TreeSet添加字符串,按照字符串首字母字母顺序和字符串长度顺序排序
通过TreeSet类直接对学生成绩实现了排序功能,不必要进行相关额外的排序来实现!
下面小编就为大家带来一篇浅谈java中的TreeMap 排序与TreeSet 排序。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、Java的面向对象。每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础...
介绍TreeSet集合用法,向TreeSet集合中添加类的对象,此类需实现Comparable接口,有实例,供需要的朋友下载学习。
Java数据结构--13.Java8数据结构TreeSet 前⾔ ,上⼀篇中对 Set 接⼝最终实现类 HashSet 与 LinkedHashSet 做了介绍与分析,本篇将对另⼀种 Set 接⼝的最终实现类 TreeSet 进⾏ 介绍与分析。 先来看下 TreeSet 完整...
public int compare(String o1,String o2) { return o1.length()-o2.length();... TreeSet ts = new TreeSet(com); ts.add("string"); ts.add("char"); ts.add("nothing�"); System.out.println(ts);
主要介绍了Java实现储存对象并按对象某属性排序的几种方法,结合实例形式详细分析了Java储存对象并按对象某属性排序的具体实现方法与操作注意事项,需要的朋友可以参考下
如果是定制排序,需要创建TreeSet对象的时候,传入一个Comparetor接口实现类对象,重写compare方法 一般是默认排序用自然排序(Comparable接口),特殊排序用定制排序(Comparetor接口实现) LinkedHashSet:如果...
此方法的实现比上一种方法的实现代码要少一些,且不需要新建集合,但此方法得到的新集合是无序的,也就是新集合的排列顺序和原集合不一致 3:HashSet去重(无序) 此方法的实现代码较为简洁,但缺点是 HashSet 会自动...
13.1.3 TreeSet类 13.1.4 向Set中加入持久化类的对象 13.2 List(列表) 13.3 Map(映射) 13.4 小结 13.5 思考题 第14章 映射值类型集合 14.1 映射Set(集) 14.2 映射Bag(包) 14.3 映射List...