关于TreeSet倒序排列和自定义排列
本文部分转自:http://blog.csdn.net/kaituozhe345/article/details/6842945
1.TreeSet的自然排序.
TreeSet存储对象的时候, 可以排序, 但是需要指定排序的算法
Integer能排序(有默认顺序), String能排序(有默认顺序), 自定义的类存储的时候出现异常(没有顺序).
TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,意味着TreeSet中的元素要实现Comparable接口。
如果要想使集合中的顺序按照降序排列的话需要用到TreeSet的descendingSet()方法.
package cn.summerchill.test; import java.util.Iterator;
import java.util.TreeSet; public class TreeSetDemo {
public static void main(String[] args) {
//String类型降序
// creating a TreeSet
TreeSet<String> treeStr = new TreeSet<String>();
TreeSet<String> treeReverseStr= new TreeSet<String>();
// adding in the tree set
treeStr.add("1");
treeStr.add("13");
treeStr.add("17");
treeStr.add("2");
// creating reverse set
treeReverseStr = (TreeSet) treeStr.descendingSet();
// create descending set
Iterator iteratorStr;
iteratorStr = treeReverseStr.iterator();
// displaying the Tree set data
System.out.println("Tree set data in reverse order for String type: ");
while (iteratorStr.hasNext()) {
System.out.println(iteratorStr.next() + " ");
} //Integer类型降序
TreeSet<Integer> tree = new TreeSet<Integer>();
TreeSet<Integer> treeReverse = new TreeSet<Integer>();
tree.add(1);
tree.add(13);
tree.add(17);
tree.add(2);
// creating reverse set
treeReverse = (TreeSet) tree.descendingSet();
// create descending set
Iterator iterator2;
iterator2 = treeReverse.iterator();
// displaying the Tree set data
System.out.println("Tree set data in reverse order for Integer type: ");
while (iterator2.hasNext()) {
System.out.println(iterator2.next() + " ");
}
}
}
打印输出:
Tree set data in reverse order for String type:
2
17
13
1
Tree set data in reverse order for Integer type:
17
13
2
1
如果存数据的集合是ArrayList或者是Linkedlist他会是原样输出,如果是一个HashSet会乱序输出,但现在TreeSet会按顺序输出。
但是如果是一个自定义的类对象输出会出现异常:
示例代码:
import java.util.TreeSet;
public class TreeSetTest2 {
public static void main(String[] args) {
TreeSet<Person> tree= new TreeSet<Person>();
tree.add(new Person("zhangran"));
tree.add(new Person("zhang"));
System.out.println(tree);
}
}
class Person
{
String name;
Person(String name)
{
this.name = name;
}
public String toString()
{
return this.name;
}
}
运行输出:
Exception in thread "main" java.lang.ClassCastException: cn.summerchill.test.Person cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(Unknown Source)
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at cn.summerchill.test.TreeSetTest2.main(TreeSetTest2.java:8)
此时此时便会出现异常,问题在于,TreeSet本来是应该比较大小,然后按顺序输出的但是,但是现在你给了他一个自己定义的类,它便无法识别,不知道怎么排序了,所以你现在所做的就是告诉他如何排序,此时就需要一个比较器.
TreeSet的两种排序方式
(1). 让元素本身具有比较性
元素本身要实现Comparable接口并实现里面的compareTo方法以保证元素本身具有比较性
(2). 让容器自身具有比较性
当元素本身不具有比较性或者具备的比较性不是所需要的,就在TreeSet建立实例的时候,传入Comparator接口的实现子类的实例。这个Comparator子类必须实现compare方法。
以下第2和第3条是这两种方式的实现.
2.TreeSet自定义类对象的排序
* 如果想把自定义类的对象存入TreeSet进行排序, 那么必须实现Comparable接口
* 在类上implement Comparable
* 重写compareTo()方法
* 在方法内定义比较算法, 根据大小关系, 返回正数负数或零
* 在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较, 根据比较结果使用二叉树形式进行存储
如果我们自己定义的一个类的对象要加入到TreeSet当中,那么这个类必须要实现Comparable接口。
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet; public class Test_treeset {
public static void main(String[] args) {
Set<Teacher> ts = new TreeSet<Teacher>();
ts.add(new Teacher("zhangsan", 1));
ts.add(new Teacher("lisi", 2));
ts.add(new Teacher("wangmazi", 3));
ts.add(new Teacher("wangwu",4));
ts.add(new Teacher("mazi", 3));
Iterator<Teacher> it = ts.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
class Teacher implements Comparable {
int num;
String name; Teacher(String name, int num) {
this.num = num;
this.name = name;
} public String toString() {
return "学号:" + num + "\t\t姓名:" + name;
} //o中存放时的红黑二叉树中的节点,从根节点开始比较
public int compareTo(Object o) {
Teacher ss = (Teacher) o;
//int result = num < ss.num ? 1 : (num == ss.num ? 0 : -1);//降序
int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1);//升序
if (result == 0) {
result = name.compareTo(ss.name);
}
return result;
}
}
打印输出:
学号:1 姓名:zhangsan
学号:2 姓名:lisi
学号:3 姓名:mazi
学号:3 姓名:wangmazi
学号:4 姓名:wangwu
3.使用比较器(Comparator)对加入的数据进行排序
在使用Arrays对数组中的元素进行排序的时候,可以传递一个比较器。
在使用Collections对集合中的元素进行排序的时候,可以传递一个比较器。
那么在使用TreeSet对加入到其中的元素进行排序的时候可以传入一个比较器吗?
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<E,Object>(comparator));
}
通过查看它的构造方法就知道可以传入一个比较器。
构造一个新的空TreeSet,它根据指定比较器进行排序。插入到该 set 的所有元素都必须能够由指定比较器进行相互比较:对于 set 中的任意两个元素 e1 和e2,执行 comparator.compare(e1, e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set 中,则 add 调用将抛出 ClassCastException。
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet; public class TreeSetTest {
public static void main(String[] args) {
TreeSet<Teacher2> ts = new TreeSet<Teacher2>(new Teacher2.TeacherCompare());
ts.add(new Teacher2("zhangsan", 2));
ts.add(new Teacher2("lisi", 1));
ts.add(new Teacher2("wangmazi", 3));
ts.add(new Teacher2("mazi", 3));
Iterator<Teacher2> it = ts.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
} class Teacher2 {
int num;
String name; Teacher2(String name, int num) {
this.num = num;
this.name = name;
} public String toString() {
return "学号:" + num + " 姓名:" + name;
} static class TeacherCompare implements Comparator {// 老师自带的一个比较器
//o1中存放的是目标节点
//o2中存放时的红黑二叉树中的节点,从根节点开始比较
public int compare(Object o1, Object o2) {
Teacher2 s1 = (Teacher2) o1;// 转型
Teacher2 s2 = (Teacher2) o2;// 转型
int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1);
if (result == 0) {
result = s1.name.compareTo(s2.name);
}
return result;
}
}
}
打印输出:
学号:1 姓名:lisi
学号:2 姓名:zhangsan
学号:3 姓名:mazi
学号:3 姓名:wangmazi
//============================================================================
下面再讲一下Collections中的某些方法,Collections是集合的父类,里面有许多的静态方法,可以给他的子类对象提供许多功能
1.让LinkedList中的数值有序输出
示例代码:
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList; public class Test2 {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<Integer>();
list.add(new Integer(1));
list.add(new Integer(0));
list.add(new Integer(3));
list.add(new Integer(2)); //生成一个比较器
Comparator com = Collections.reverseOrder();//倒叙
Collections.sort(list,com);//list按照com的排列反方式排列. //Collections.reverse(list);按照输入相反的顺序排列输出
//Collections.shuffle(list);乱序排列
//Collections.min(list);//集合中的最小值
//Collections.max(list);//集合中的最大值 }
}
2.Collections.shuffle()乱序排列。。。。
3.Collections.min();最小
4.Collections.max();最大
关于TreeSet倒序排列和自定义排列的更多相关文章
- java_泛型 TreeSet 判断hashcode/length(升序排列)
package ming; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; ...
- 现有‘abcdefghijkl’12个字符,将其所有的排列按字典序进行排序,给出任意一组排列,说出这租排列在所有排列中是第几小的
题目: 现有‘abcdefghijkl’12个字符,将其所有的排列按字典序进行排序,给出任意一组排列,说出这租排列在所有排列中是第几小的 据说这道题是百度校招的一道算法题,反正我觉得我在学校的时候很可 ...
- 【数论·错位排列】bzoj4517 排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1428 Solved: 872[Submit][Statu ...
- BZOJ.4517.[SDOI2016]排列计数(错位排列 逆元)
题目链接 错位排列\(D_n=(n-1)*(D_{n-1}+D_{n-2})\),表示\(n\)个数都不在其下标位置上的排列数. 那么题目要求的就是\(C_n^m*D_{n-m}\). 阶乘分母部分的 ...
- TreeSet的自然排序(自定义对象 compareTo方法)
>要实现自然排序,对象集合必须实现Comparable接口,并重写compareTo()方法 >一般需求中描述的是"主要条件",如:按姓名长度排序. 需注意次要条件 ...
- [BZOJ4517][SDOI2016]排列计数(错位排列)
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1616 Solved: 985[Submit][Statu ...
- Java修炼——插入排列,选择排列
话不多说,直接上代码: package com.bjsxt.Array; import java.util.Arrays; public class TestSort { //选择排序 //插入排列 ...
- 【BZOJ4517】排列计数(排列组合)
题意:1-n的一个序列,其中有m个a[i]=i,求方案数 n,m<=1000000 题意:显然ANS=c(n,m)*d[n-m] d[i]为错排方案数=d[i-1]*n+(-1)^n ; ..] ...
- django models返回数据根据某字段倒序排列
例如有一个models表叫做report,report表中有一个endtime,想将结果按照endtime倒序排列 正序排列的方法:[models对象.objects.order_by(“字段名& ...
随机推荐
- 2016 CocosPods安装教程
CocoaPods简介 CocoaPods是一个管理Swift和Objective-C的Cocoa项目的依赖工具.它现在有超过一万八千多个库,可以优雅地帮助你扩展你的项目.简单的说,就是替你管理Swi ...
- zznu 1914 asd的甩锅计划
http://acm.zznu.edu.cn/problem.php?id=1914 asd的甩锅计划 时间限制: 1 Sec 内存限制: 128 MB提交: 114 解决: 10[提交][状态] ...
- UIButton上使用UIEdgeInsetsMake让title跟图片对齐
UIButton上使用UIEdgeInsetsMake让title跟图片对齐 默认情况下,不设置的效果,都使居中现实,button为150*150 使用以下设置后: [self setTitleE ...
- Java NIO类库Selector机制解析(上)
一. 前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...
- Egret项目Typescript的编译报错
今天编译项目,出现了一个奇怪的报错,如下: E:\engine\egret-core-3.1.2\tools\lib\typescript\tsclark.js:41531 1> if (fil ...
- ios8,xcode6 周边
NSBundle.mainBundle().infoDictionary iOS 8中带按钮的推送代码 ") ){ application.registerForRemoteNotifica ...
- PL/pgSQL的RETURN QUERY例子
我的例子: 数据准备: create table custinfo(custid integer,callingcnt integer); ,),(,),(,); 函数生成: CREATE OR RE ...
- Spring连接数据库的几种常用的方式
本文简单的讲解使用Spring连接数据库的几种常用方法: 测试主类为: package myspring2; import java.sql.*; import javax.sql.DataSourc ...
- centos环境配置
1. centos上安装开发环境 yum groupinstall "Development Tools" "Legacy Software Development&qu ...
- Codeforces Round #278 (Div. 1) A. Fight the Monster 暴力
A. Fight the Monster Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/487/ ...