关于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(“字段名& ...
随机推荐
- c函数调用过程原理及函数栈帧分析
转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707 今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比 ...
- java数字保留两位小数四舍五入
import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; public c ...
- MVC生命周期
MVC之前的那点事儿系列 转自:http://www.cnblogs.com/TomXu/p/3756794.html http://www.cnblogs.com/Joans/archive/201 ...
- 删除目录下的所有".svn"文件
丢一段python代码: # -*- coding: cp936 -*- import os import re import shutil '''找出路径base(包括子目录)下所有符合patter ...
- Swift学习笔记二
Swift是苹果公司开发的一门新语言,它当然具备面向对象的许多特性,现在开始介绍Swift中类和对象的语法. 对象和类 用"class"加上类名字来创建一个类,属性声明和声明常量或 ...
- Linux - 打印文件夹全部文件 代码(C)
列出文件夹全部文件 代码(C) 本文地址:http://blog.csdn.net/caroline_wendy 首先配置环境,參考:http://blog.csdn.net/caroline_wen ...
- JavaEE系列之(一)JSP基础知识详解
一.JSP基础语法 1.JSP简介 JSP(Java Server Pages),其根本是一个简化的Servlet设计,它实现了在Java中使用HTML标签.JSP是一种动态网页 ...
- iOS开发——网络编程Swift篇&(六)异步Post方式
异步Post方式 // MARK: - 异步Post方式 func asynchronousPost() { //创建NSURL对象 var url:NSURL! = NSURL(string: &q ...
- 如何在Ubuntu 13.04中升级到 GNOME 3.8
如何在Ubuntu 13.04中升级到 GNOME 3.8 添加 GNOME 3 PPA(Personal Package Archives) 在你进一步浏览之前,确认你正在运行的是Ubuntu 13 ...
- C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...