【自然排序】

 package com.hxl;

 public class Student implements Comparable<Student> {

     private String name;
private int age; public Student() {
super();
} public Student(String name, int age) {
super();
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public int compareTo(Student s) {
// 先让两个对象的age属性做差比较,这个是主要排序条件
int num = this.age - s.age;
// 若age属性相同,再比较name属性(String类本身实现了Comparable接口)
// 即在主要排序条件相同的情况下,次要排序条件起作用
int flag = num == 0 ? this.name.compareTo(s.name) : num;
// 返回比较结果
return flag;
}
}
 package com.hxl;

 import java.util.TreeSet;

 public class Test {
public static void main(String[] args) {
//这里使用的无参构造实例化TreeSet集合,则默认启用的是自然排序
TreeSet<Student> ts = new TreeSet<Student>();
ts.add(new Student("cc", 11));
ts.add(new Student("ee", 11));
ts.add(new Student("cc", 22));
ts.add(new Student("aa", 22));
ts.add(new Student("bb", 11)); for (Student s : ts) {
System.out.println(s.getName()+"_"+s.getAge());
} /*
为什么TreeSet集合中的元素既唯一又有序呢?
原因是它在存储元素的时候就是有序存储的(红黑树结构存储)
TreeSet的add()方法底层依赖的是Comparable的compareTo方法
这里就是说元素类本身要有自己的compareTo方法
所以元素类本身必须实现Comparable接口,重写compareTo方法
compareTo方法有个特点:它返回的是int型数据,结果有三类负数、0、正数
例如:(Java中一些常见的有比较意义的一些类都实现了Comparable接口,如Integer类)
Integer a = new Integer(10);
Integer b = new Integer(20);
int num = a.compareTo(b); //因为a小于b,所以num返回的是负数
而TreeSet的add()方法这样理解此返回值:
即返回负数则比根节点小,元素在此集合中唯一,元素存放根的左孩子
返回正数则比根节点大,元素在此集合中唯一,元素存放根的右孩子
返回0则表示,元素相同,在此集合中不唯一,故而丢掉不存放
由此可见,我们的重写的compareTo()方法决定了TreeSet集合中元素的去留和顺序!
*/
}
}

【比较器排序(外部类实现)】

 package com.hxl;

 public class Student{

     private String name;
private int age; public Student() {
super();
} public Student(String name, int age) {
super();
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}
 package com.hxl;

 import java.util.Comparator;

 public class MyComparator implements Comparator<Student> {

     @Override
public int compare(Student s1, Student s2) {
// 先让两个对象的age属性做差比较,这个是主要排序条件
int num = s1.getAge() - s2.getAge();
// 若age属性相同,再比较name属性(String类本身实现了Comparable接口)
// 即在主要排序条件相同的情况下,次要排序条件起作用
int flag = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
// 返回比较结果
return flag;
}
}
 package com.hxl;

 import java.util.TreeSet;

 public class Test {
public static void main(String[] args) {
//这里使用TreeSet(Comparator comparator)构造实例化TreeSet集合,则启用的是指定比较器排序
TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());
ts.add(new Student("cc", 11));
ts.add(new Student("ee", 11));
ts.add(new Student("cc", 22));
ts.add(new Student("aa", 22));
ts.add(new Student("bb", 11)); for (Student s : ts) {
System.out.println(s.getName()+"_"+s.getAge());
}
}
}

【比较器排序(内部类实现,如果只使用一次的话)】

 package com.hxl;

 public class Student{

     private String name;
private int age; public Student() {
super();
} public Student(String name, int age) {
super();
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}
 package com.hxl;

 import java.util.Comparator;
import java.util.TreeSet; public class Test {
public static void main(String[] args) {
//如果一个方法的参数是接口,那么真实想要的是其实是接口实现类的对象
//这里的对象只用一次,专门定义一个外部类显得麻烦
//匿名内部类可以实现这个需求
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
public int compare(Student s1, Student s2) {
// 先让两个对象的age属性做差比较,这个是主要排序条件
int num = s1.getAge() - s2.getAge();
// 若age属性相同,再比较name属性(String类本身实现了Comparable接口)
// 即在主要排序条件相同的情况下,次要排序条件起作用
int flag = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
// 返回比较结果
return flag;
}
});
ts.add(new Student("cc", 11));
ts.add(new Student("ee", 11));
ts.add(new Student("cc", 22));
ts.add(new Student("aa", 22));
ts.add(new Student("bb", 11)); for (Student s : ts) {
System.out.println(s.getName()+"_"+s.getAge());
}
}
}

【注】开发中会用最后一种,因为第一种只有固定的排序方式,第二种每次都要定义外面类显得麻烦。

TreeSet集合的自然排序与比较器排序、Comparable接口的compareTo()方法的更多相关文章

  1. 什么是泛型?,Set集合,TreeSet集合自然排序和比较器排序,数据结构-二叉树,数据结构-平衡二叉树

    ==知识点== 1.泛型 2.Set集合 3.TreeSet 4.数据结构-二叉树 5.数据结构-平衡二叉树 ==用到的单词== 1.element[ˈelɪmənt] 要素 元素(软) 2.key[ ...

  2. TreeSet对非自然顺序元素的排序

    /* 1. 往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储. 2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该 ...

  3. TreeSet集合如何保证元素唯一

    TreeSet: 1.特点 TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列 2.使用方式 a.自然顺序(Comparable) TreeSet类的add()方法中会 ...

  4. java通过Comparable接口实现字符串比较大小排序的简单实例

    /** * 对象比较大小compare的用法 字符串排序 * 练习代码, 给定字符串" nba" "cba" "ncaa" "wb ...

  5. Java—集合框架 Collections.sort()、Comparable接口和Comparator接口

    Collentions工具类--java.util.Collections Collentions是Java集合框架中,用来操作集合对象的工具类,也是Java集合框架的成员,与List.Map和Set ...

  6. 《java入门第一季》之集合框架TreeSet存储元素自然排序以及图解

    这一篇对TreeSet做介绍,先看一个简单的例子: * TreeSet:能够对元素按照某种规则进行排序.  * 排序有两种方式  * A:自然排序: 从小到大排序  * B:比较器排序    Comp ...

  7. TreeSet集合的add()方法源码解析(01.Integer自然排序)

    >TreeSet集合使用实例 >TreeSet集合的红黑树 存储与取出(图) >TreeSet的add()方法源码     TreeSet集合使用实例 package cn.itca ...

  8. TreeSet集合排序方式一:自然排序Comparable

    TreeSet集合默认会进行排序.因此必须有排序,如果没有就会报类型转换异常. 自然排序 Person class->实现Comparable,实现compareTo()方法 package H ...

  9. TreeSet 比较器排序 自定义对象

    package cn.itcast.day21.treeset2; import java.util.Comparator; import java.util.TreeSet; /* * TreeSe ...

随机推荐

  1. Go语言从入门到放弃(三) 布尔/数字/格式化输出

    本章主要介绍Go语言的数据类型 布尔(bool) 布尔指对或者错,也就是说bool只有两个值, True 或 False 两个类型相同的值可以使用比较运算符来得出一个布尔值 当两个值是完全相同的情况下 ...

  2. 轻松搞懂elasticsearch概念

      本文主要介绍elasticsearch6.0的一些基本概念,有助于深入理解.研究elasticsearch和elk系统 一图胜千言 elasticsearch与mysql参照来看 添加一条数据 紫 ...

  3. Confluence 6 附件存储提取文本文件

    当基于文本的文件上传到 Confluence(例如,Word,PowerPoint 等),这些文件中的文本是可以提取并且添加到索引中的,用户可以通过索引来搜索这些文件中的文本内容,不仅仅是搜索文件名. ...

  4. Confluence 6 配置站点主页面

     主面板(dashboard)是你站点的默认主页,但是你也可以选择使用一个空间的主页为网站访问的首页面. 针对你的 Confluence 站点主要是为用户进行阅读而不是创建内容的话,这样的配置就显得非 ...

  5. Confluence 6 升级自定义的站点和空间布局

    随着 Confluence 的演变.默认的站点和空间布局也会随着 Confluence 升级而让使用的所有页面进行改变.随着一些新功能的加入和一些老功能的修改,默认的布局也需要进行修改来支持这些改变. ...

  6. shell中的ps命令详解

    ps简介:Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的 ...

  7. LeetCode(124):二叉树中的最大路径和

    Hard! 题目描述: 给定一个非空二叉树,返回其最大路径和. 本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列.该路径至少包含一个节点,且不需要经过根节点. 示例 1: 输入: [1, ...

  8. 2017-2018-2 20165314 实验三《 敏捷开发与XP实践》实验报告

    知识点: 1.XP团队使用现场客户.特殊计划方法和持续测试来提供快速的反馈和全面的交流: -XP是以开发符合客户需要的软件为目标而产生的一种方法论 -XP是一种以实践为基础的软件工程过程和思想 -XP ...

  9. trade war

    问题 C: trade war 时间限制: 1 Sec  内存限制: 128 MB 题目描述 2018年的春天,特朗普这个不靠谱的的家伙悍然向中国发起了贸易战,贸易战是一场没有赢家的战争,美国向中国商 ...

  10. Vue注意事项及用得较多的属性归纳

    1.prop是一个对象而不是字符串数组时,它包含验证要求.props: { // 基础类型检测 (`null` 意思是任何类型都可以) propA: Number, // 多种类型 propB: [S ...