关于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(“字段名& ...
随机推荐
- Maven构建Web项目问题汇总
1.Dynamic Web Module 3.0 requires Java 1.6 or newer? 修改pom.xml文件,如下: <build> <plugins> & ...
- firefox 对相对定位的TD元素渲染错误
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv=&quo ...
- (转)UML序列图总结
序列图主要用于展示对象之间交互的顺序. 序列图将交互关系表示为一个二维图.纵向是时间轴,时间沿竖线向下延伸.横向轴代表了在协作中各独立对象的类元角色.类元角色用生命线表示.当对象存在时,角色用一条虚线 ...
- JSF 2 textbox example
In JSF, you can use the <h:inputText /> tag to render a HTML input of type="text", t ...
- ASP.NET MVC- 数据验证机制
ASP.NET MVC的数据验证机制,比起ASP.NET WEBFORM那种高效很多.下面记录以下两个示例,以便日后方便查阅. 方式一:在Controller里通过AddModelError方法返回错 ...
- 工具栏停靠实现(toolbar docking)
// TODO: 如果不需要工具栏可停靠,则删除这三行 m_ToolBar_File.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_A ...
- Understanding CloudStack’s Physical Networking Architecture
Understanding and configuring the physical connections of a host in a CloudStack deployment can at f ...
- C字符串压缩算法
#include <iostream> #include <stdlib.h> //#include <algorithm> using namespace std ...
- IOC运用到MVC中
IOC可以摒弃掉类中类的紧耦合,让设计和重用更简单,将IOC加入到MVC中的实现非常简单,那么有哪几种方法?它们的实现又是什么原理呢? IOC在MVC中的注入,主要是在获取Controller对象中实 ...
- Codeforces Round #328 (Div. 2) B. The Monster and the Squirrel 打表数学
B. The Monster and the Squirrel Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/c ...