TreeSet集合的自然排序与比较器排序、Comparable接口的compareTo()方法
【自然排序】
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()方法的更多相关文章
- 什么是泛型?,Set集合,TreeSet集合自然排序和比较器排序,数据结构-二叉树,数据结构-平衡二叉树
==知识点== 1.泛型 2.Set集合 3.TreeSet 4.数据结构-二叉树 5.数据结构-平衡二叉树 ==用到的单词== 1.element[ˈelɪmənt] 要素 元素(软) 2.key[ ...
- TreeSet对非自然顺序元素的排序
/* 1. 往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储. 2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该 ...
- TreeSet集合如何保证元素唯一
TreeSet: 1.特点 TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列 2.使用方式 a.自然顺序(Comparable) TreeSet类的add()方法中会 ...
- java通过Comparable接口实现字符串比较大小排序的简单实例
/** * 对象比较大小compare的用法 字符串排序 * 练习代码, 给定字符串" nba" "cba" "ncaa" "wb ...
- Java—集合框架 Collections.sort()、Comparable接口和Comparator接口
Collentions工具类--java.util.Collections Collentions是Java集合框架中,用来操作集合对象的工具类,也是Java集合框架的成员,与List.Map和Set ...
- 《java入门第一季》之集合框架TreeSet存储元素自然排序以及图解
这一篇对TreeSet做介绍,先看一个简单的例子: * TreeSet:能够对元素按照某种规则进行排序. * 排序有两种方式 * A:自然排序: 从小到大排序 * B:比较器排序 Comp ...
- TreeSet集合的add()方法源码解析(01.Integer自然排序)
>TreeSet集合使用实例 >TreeSet集合的红黑树 存储与取出(图) >TreeSet的add()方法源码 TreeSet集合使用实例 package cn.itca ...
- TreeSet集合排序方式一:自然排序Comparable
TreeSet集合默认会进行排序.因此必须有排序,如果没有就会报类型转换异常. 自然排序 Person class->实现Comparable,实现compareTo()方法 package H ...
- TreeSet 比较器排序 自定义对象
package cn.itcast.day21.treeset2; import java.util.Comparator; import java.util.TreeSet; /* * TreeSe ...
随机推荐
- Linux虚拟串口
将下列Python代码保存成VitrualCom.py: Code#! /usr/bin/env python #coding=utf-8 import pty import os import se ...
- [MySQL]join的细节
left join,左表返回所有记录,右表只返回跟左表有关联的记录,当右表有N条记录跟左表的某一条记录A关联,那么查询结果会出现N条A记录(相应关联右表的N条记录) right join,右表返回所有 ...
- CSS弹性(flexible)盒子
弹性盒子 弹性盒子由弹性容器(Flex container)和弹性子元素(Flex item)组成 弹性容器通过display:flex | inline-flex将其定义为弹性容器 ...
- SQL Server 2016 Failover Cluster + ALwaysOn
SQL Server 2016 Failover Cluster + ALwaysOn 环境的搭建 近期公司为了提高服务的可用性,就想到了部署AlwaysOn,之前的环境只是部署了SQL Server ...
- Pl/SQL 编程
Pl/SQL 编程 一:前言 二:Pl/Sql 概述 二 —— 1: Pl/Sql块结构 [declare] --声明部分,可选 begin --执行部分,必须 [exception] -- ...
- ios 输入框问题
去除ios输入框阴影 input,textarea{-webkit-appearance:none; outline: none; } ios有边框时设置boder-radius:0: 去除默认圆角问 ...
- MySQL外键使用详解
一.基本概念 1.MySQL中“键”和“索引”的定义相同,所以外键和主键一样也是索引的一种.不同的是MySQL会自动为所有表的主键进行索引,但是外键字段必须由用户进行明确的索引.用于外键关系的字段必须 ...
- Linux基础一:Linux的安装及相关配置
1. 计算机操作系统简介 1) 操作系统的定义:操作系统是一个用来协调.管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间. 2) 操作系统的内核的定义:操作系统的内核是一 ...
- re模块(正则)
一, 什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法. 在python中,正则内嵌在python中,并通过re模块实现,正则表达模式被编译成一系列 ...
- hive内group by取第一条数据,Hive中row_number的使用
1.hive的分组和组内排序---语法 语法: row_number() over (partition by 字段a order by 计算项b desc ) rank rank是排序的别名 par ...