1.排序的引入

由于TreeSet可以实现对元素按照某种规则进行排序,例如下面的例子

 public class TreeSetDemo {
public static void main(String[] args) {
// 创建集合对象
// 自然顺序进行排序
TreeSet<Integer> ts = new TreeSet<Integer>(); // 创建元素并添加
// 20,18,23,22,17,24,19,18,24
ts.add(20);
ts.add(18);
ts.add(23);
ts.add(22);
ts.add(17);
ts.add(24);
ts.add(19);
ts.add(18);
ts.add(24); // 遍历
for (Integer i : ts) {
System.out.println(i);
}
}
}

运行结果为:

但是对自定义对象呢?

 public class TreeSetDemo02 {
public static void main(String[] args) {
TreeSet<Student> ts=new TreeSet<Student>();
//创建元素对象
Student s1=new Student("zhangsan",20);
Student s2=new Student("lis",22);
Student s3=new Student("wangwu",24);
Student s4=new Student("chenliu",26);
Student s5=new Student("zhangsan",22);
Student s6=new Student("qianqi",24); //将元素对象添加到集合对象中
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6); //遍历
for(Student s:ts){
System.out.println(s.getName()+"-----------"+s.getAge());
}
}
}

Student类:

 public class Student {
private String name;
private int age; public Student() {
super();
// TODO Auto-generated constructor stub
} 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;
}
}

运行结果:

原因分析:
由于不知道该安照那一中排序方式排序,所以会报错。
 
解决方法:
   1.自然排序
2.比较器排序

2.自然排序

自然排序要进行一下操作:
 
1.Student类中实现  Comparable<T>接口
2.重写Comparable接口中的Compareto方法
int compareTo(T o)
          比较此对象与指定对象的顺序。

故Student类为:特别注意在重写Compareto方法时,注意排序

 package xfcy_04;
/**
* Student类
* @author 晓风残月
*
*/
public class Student implements Comparable<Student> {
private String name;
private int age; public Student() {
super();
// TODO Auto-generated constructor stub
} 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) {
//return -1; //-1表示放在红黑树的左边,即逆序输出
//return 1; //1表示放在红黑树的右边,即顺序输出
//return o; //表示元素相同,仅存放第一个元素
//主要条件 姓名的长度,如果姓名长度小的就放在左子树,否则放在右子树
int num=this.name.length()-s.name.length();
//姓名的长度相同,不代表内容相同,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。
//如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。
//如果这两个字符串相等,则结果为 0
int num1=num==0?this.name.compareTo(s.name):num;
//姓名的长度和内容相同,不代表年龄相同,所以还要判断年龄
int num2=num1==0?this.age-s.age:num1;
return num2;
} }

而主类中为:

 package xfcy_04;

 import java.util.TreeSet;

 /*
* TreeSet存储自定义对象并保证排序和唯一。
*
* 需求:请按照姓名的长度排序
*/
public class TreeSetDemo02 {
public static void main(String[] args) {
//创建集合对象
TreeSet<Student> ts=new TreeSet<Student>(); //创建元素对象
Student s1=new Student("zhangsan",20);
Student s2=new Student("lis",22);
Student s3=new Student("wangwu",24);
Student s4=new Student("chenliu",26);
Student s5=new Student("zhangsan",22);
Student s6=new Student("qianqi",24); //将元素对象添加到集合对象中
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6); //遍历
for(Student s:ts){
System.out.println(s.getName()+"-----------"+s.getAge());
}
}
}

运行结果:

3、比较器排序

比较器排序步骤:
1.单独创建一个比较类,这里以MyComparator为例,并且要让其继承Comparator<T>接口
2.重写Comparator接口中的Compare方法
 
3.在主类中使用下面的 构造方法
 

TreeSet(Comparator<? superE> comparator) 
          构造一个新的空 TreeSet,它根据指定比较器进行排序。
 
 
主类:
 package xfcy_04;

 import java.util.TreeSet;

 /*
* TreeSet存储自定义对象并保证排序和唯一。
*
* 需求:请按照姓名的长度排序
*/
public class TreeSetDemo02 {
public static void main(String[] args) {
//创建集合对象
//TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。
TreeSet<Student> ts=new TreeSet<Student>(new MyComparator()); //创建元素对象
Student s1=new Student("zhangsan",20);
Student s2=new Student("lis",22);
Student s3=new Student("wangwu",24);
Student s4=new Student("chenliu",26);
Student s5=new Student("zhangsan",22);
Student s6=new Student("qianqi",24); //将元素对象添加到集合对象中
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6); //遍历
for(Student s:ts){
System.out.println(s.getName()+"-----------"+s.getAge());
}
}
}

MyComparator类:

 package xfcy_04;

 import java.util.Comparator;

 public class MyComparator implements Comparator<Student>{

     @Override
public int compare(Student s1,Student s2) {
// 姓名长度
int num = s1.getName().length() - s2.getName().length();
// 姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
// 年龄
int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
} }

学生类(不需要继承Comparetable接口)

 package xfcy_04;
/**
* Student类
* @author 晓风残月
*
*/
public class Student{
private String name;
private int age; public Student() {
super();
// TODO Auto-generated constructor stub
} 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;
} }

运行结果:

4.比较器修改(代码精简)

由于单独创建一个类不是特别好,因而可以将MyComparetor的内容直接写到主类中

 public class TreeSetDemo {
public static void main(String[] args) {
// 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象
// 而匿名内部类就可以实现这个东西
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 姓名长度
int num = s1.getName().length() - s2.getName().length();
// 姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
: num;
// 年龄
int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
}
}); // 创建元素
Student s1 = new Student("linqingxia", 27);
Student s2 = new Student("zhangguorong", 29);
Student s3 = new Student("wanglihong", 23);
Student s4 = new Student("linqingxia", 27);
Student s5 = new Student("liushishi", 22);
Student s6 = new Student("wuqilong", 40);
Student s7 = new Student("fengqingy", 22);
Student s8 = new Student("linqingxia", 29); // 添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
ts.add(s7);
ts.add(s8); // 遍历
for (Student s : ts) {
System.out.println(s.getName() + "---" + s.getAge());
}
}
}
运行结果也如同上面一样
 

5.总结

A:自然排序:要在自定义类中实现Comparerable<T>接口  ,并且重写compareTo方法
B:比较器排序:在自定义类中实现Comparetor<t>接口,重写compare方法

TreeSet的两种排序方式,含Comparable、Comparator的更多相关文章

  1. [Java]HashMap的两种排序方式

    先将 Map 中的 key 和 value 全部取出来封装成 JavaBea 数组,再将这个数组排序,排序完成后,重新写回 Map 中,写回时采用 LinkedHashMap 可以保证迭代的顺序. 下 ...

  2. HashMap的两种排序方式

    Map<String, Integer> map = new HashMap<String, Integer>();map.put("d", 2);map. ...

  3. TreeSet的两种实现方法:Comparable和Comparator(Java比较器)

    Comparable与Comparator实际上是TreeSet集合的两种实现方式,用来实现对象的排序.下边介绍一下两种比较器的使用方法和区别. Comparable称为元素的自然顺序,或者叫做默认顺 ...

  4. java List递归排序,传统方式和java8 Stream优化递归,无序的列表按照父级关系进行排序(两种排序类型)

    当有一个List列表是无序的,List中的数据有parentid进行关联,通过java排序成两种排序类型: 所用的测试列表最顶级无parentid,若为特殊值,修改下判断方法即可. 第一种排序:按照树 ...

  5. Android 常用UI控件之TabHost(1)TabHost的两种布局方式

    TabHost是Android中的tab组件. TabHost布局文件的基本结构 TabHost下有个layout,这个layout中有TabWidget与FrameLayout.TabWidget是 ...

  6. 巨蟒python全栈开发数据库前端6:事件onclick的两种绑定方式&&onblur和onfocus事件&&window.onload解释&&小米商城讲解

    1.回顾上节内容(JavaScript) 一.JavaScript概述 1.ECMAScript和JavaScript的关系 2.ECMAScript的历史 3.JavaScript是一门前后端都可以 ...

  7. CList 点击表头排序 (2)两种排序方法中其中一种

    上一篇讲解SortItem()方法如何使用,虽然都是抄别人的但是就是想让大家有个大概的了解 CList 点击表头排序 (1)SortItems函数 点击表头排序基本思路都是 1.首先响应HDN_ITE ...

  8. POJ 2299-Ultra-QuickSort-线段树的两种建树方式

    此题有两种建树方式! Description In this problem, you have to analyze a particular sorting algorithm. The algo ...

  9. ch1_6_1求解两种排序方法问题

    考拉有n个字符串字符串,任意两个字符串长度都是不同的.  考拉最近学习到有两种字符串的排序方法:   1.根据字符串的字典序排序.例如: "car" < "carr ...

随机推荐

  1. angular5 @viewChild @ContentChild ElementRef renderer2

    @viewChild 作用一:选择组件内节点 <!--视图 --> <div #mydiv><input></div> // 选择 @ViewChild ...

  2. vue中操作cookie的插件

    js-cookie 安装: npm i js-cookie import Cookies from 'js-cookie' 具体用法: 写入: Cookies.set('name', 'value') ...

  3. django2_开发web系统接口

    1.单独创建.../sign/views_if.py文件,开发添加发布会接口 from django.http import JsonResponse from cmdb.models import ...

  4. django1

    * <pre>━━━━━━神兽出没━━━━━━ * ┏┓ ┏┓ * ┏┛┻━━━┛┻┓ * ┃ 王 ┃ * ┃   ┃ * ┃ ┳┛ ┗┳ ┃ * ┃ ┃ * ┃ ┻ ┃ * ┃ ┃ * ...

  5. 关于NOIP复赛规模的规定

    近年来NOIP初赛参赛人数不断增长,复赛规模也相应扩大,但仍不能满足选手积极参赛及扩大普及面的需求,现对NOIP复赛规模的规则调整如下. 1.每个省赛区可以设立多于两个的复赛考点,但必须在同一个城市, ...

  6. LeetCode刷题 fIRST MISSING POSITIVE

    Given an unsorted integer array,find missing postive integer. For example , Given [1,2,0]return 3, a ...

  7. bzoj1452

    题解: 二位树状数组 然后我开了300*300*300就T了 代码: #include<bits/stdc++.h> using namespace std; ; ],q; int fin ...

  8. day33-python阶段性复习七

    rc脚本练习 #!/usr/bin/env python #coding:utf8 import sys import os from subprocess import Popen, PIPE cl ...

  9. python全栈开发笔记---------数据类型-----字典dict

    字典 #dict #1.基本结构 info= { "k1" : "v1", #键值对 "k2" : "v2" } ### ...

  10. vue bus的使用

    vue中的bus事件,一般作为中央事件总线来使用 简单例子:比如在A,B组件为兄弟组件,现在A要调用B的中C事件 1.创建一个bus.js 内容: import Vue from 'vue' cons ...