java提高(7)---TreeSet--排序
2017-12-06 17:56
232 查看
TreeSet(一)
一、TreeSet定义:
与HashSet是基于HashMap实现一样,TreeSet同样是基于TreeMap实现的。1)TreeSet类概述
使用元素的自然顺序对元素进行排序
或者根据创建 set 时提供的 Comparator 进行排序
具体取决于使用的构造方法。
2)TreeSet是如何保证元素的排序和唯一性的
底层数据结构是红黑树(红黑树是一种自平衡的二叉树)
(1) 自然排序
import java.util.TreeSet; /** TreeSet集合的特点:排序和唯一 * * 通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法。 */ public class TreeTest1 { public static void main(String[] args) { // 创建集合对象 // 自然顺序进行排序 TreeSet<Integer> treeSet = new TreeSet<Integer>(); // 创建元素并添加 treeSet.add(8); treeSet.add(4); treeSet.add(5); treeSet.add(6); treeSet.add(6); // 遍历 for(Integer i : treeSet){ System.out.print(i); } } } /*后台输出:4568 重复会被覆盖*/
(2)如果存入对象怎么排序,记住如果是对象一定要重写Comparator方法
[b] People对象[/b]
public class People implements Comparable { private String name; private String sex; private int age; /*提供set和get方法,全参和无参构造方法*/ @Override public int compareTo(Object o) { People people = (People) o; if (people.age > this.age) { return 1; } if (this.age == people.age) { return this.name.compareTo(people.name); } if ( people.age<this.age ) { return -1; } return 0; } }
测试类
public class SortTest { public static void main(String[] args) { People people1 = new People("小a", "男", 18); People people2 = new People("小a", "女", 16); People people3 = new People("小c", "女", 18); People people4 = new People("小b", "女", 22); People people5 = new People("小d", "男", 19); Set<People> treeSet = new TreeSet<People>(); treeSet.add(people1); treeSet.add(people2); treeSet.add(people3); treeSet.add(people4); treeSet.add(people5); Iterator iterator = treeSet.iterator(); while (iterator.hasNext()) { People people = (People) iterator.next(); System.out.println("姓名:" + people.getName() + "\t年龄:" + people.getAge()); } } }
运行结束:后台报错:
Exception in thread "main" java.lang.ClassCastException: com.treeset.sort.People cannot be cast to java.lang.Comparable
![](https://images2017.cnblogs.com/blog/1090617/201712/1090617-20171206175143925-1712657226.png)
(3)举例一个学生有语文、数学、 英语三门课,按总分从高到底排序
Student对象
public class Student { private String name; private int chinese; private int math; private int english; /*提供set和get方法,同时提供无参数,有参数构造方法*/ //同时单独要加上getSum方法 public int getSum(){ return this.chinese + this.english + this.math; } }
测试类
import java.util.Iterator; import java.util.TreeSet; public class TreeTest2 { public static void main(String[] args) { Student student1=new Student("小明", 80, 90, 70); Student student2=new Student("小王", 60, 80, 90); Student student3=new Student("小钱", 100, 100, 80); Student student4=new Student("小徐", 20, 10, 90); Student student5=new Student("小李", 80, 80, 80); Student student6=new Student("小李", 70, 80, 90); TreeSet<Student> treeSet=new TreeSet(new MyComparable()); treeSet.add(student1); treeSet.add(student2); treeSet.add(student3); treeSet.add(student4); treeSet.add(student5); treeSet.add(student6); Iterator<Student> iterator=treeSet.iterator(); while(iterator.hasNext()){ Student student=iterator.next(); System.out.println(student.toString()); } } }
MyComparable类
import java.util.Comparator; public class MyComparable implements Comparator<Student>{ @Override public int compare(Student s1, Student s2) { // 总分从高到低(注意这里是s2减s1) int num = s2.getSum() - s1.getSum(); if(num>0){ return 1; } if(num<0){ return -1; } if(num==0){ //这步非常关键,没有这个如果总成绩相同名字不同 ,那set集合就默认是相同元素,就会被覆盖掉 return s2.getName().compareTo(s1.getName()); } return 0; } }
![](https://images2017.cnblogs.com/blog/1090617/201712/1090617-20171206175348488-361079397.png)
/** * 是不是很奇怪为什么只有五条数据,而不是六条,那是因为有一条数据被覆盖了。 * 你的Comparator实现类,是先比较成绩,成绩相同,在比较名字,那如果总成绩 * 相同,姓名也相同,那不是默认是重复数据,TreeSet当然给你覆盖掉了。所以这 * 里有个小李被覆盖掉了。那如何写才规范,下面这样就不会出现覆盖。 */ @Override // 创建一个TreeSet集合 public int compare(Student s1, Student s2) { // 总分从高到低(注意这里是s2减s1) int num = s2.getSum() - s1.getSum(); // 总分相同的不一定语文相同 int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num; // 总分相同的不一定数学相同 int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2; // 总分相同的不一定英语相同 int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3; // 姓名还不一定相同 int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName()) : num4; return num5; }
最后在思考,set集合在开发中到底有啥用,好像我们开发当中要用集合一般会用ArrayList,好像很少用到TreeSet集合
这个时候你就要想TreeSet集合的特点了:排序和唯一
举个小例子:
(4) 编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
import java.util.Iterator; import java.util.TreeSet; import java.util.Random; /* * 编写一个程序,获取10个1至20的随机数,要求随机数不能重复。 * * 分析: * A:创建随机数对象 * B:创建一个TreeSet集合 * C:判断集合的长度是不是小于10 * 是:就创建一个随机数添加 * 否:不搭理它 * D:遍历TreeSet集合 */ public class HashSetDemo { public static void main(String[] args) { // 创建随机数对象 Random r = new Random(); // 创建一个Set集合 TreeSet<Integer> treeSet = new TreeSet<Integer>(); // 判断集合的长度是不是小于10 while (treeSet.size() < 10) { int x = r.nextInt(20) + 1; treeSet.add(x); } // 遍历Set集合 for (int x : treeSet) { System.out.println(x); } } }
用这个例子,希望你能有扩散你的思维,也应该知道在什么时候用TreeSet集合了。
水滴石穿,成功的速度一定要超过父母老去的速度! 少尉【1】
相关文章推荐
- [个人博客搬运][Java]别写排序了,用TreeSet
- JAVA之旅(二十)—HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习
- Java提高 - 八大排序方法之快速排序
- Java提高篇(二八)------TreeSet
- 提高你的Java代码质量吧:中文字符串排序的瑕疵
- Java - TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
- Java 往TreeSet集合中存储自定义对象学生,按照学生的年龄进行排序。
- 【java】TreeSet的定制排序
- java中的几种泛型类——HashSet、HashMap、TreeSet、TreeMap,遍历map,排序,HashTable比较
- Java提高 - 八大排序方法之堆排序
- java 使用TreeSet将字符串中的数值进行排序
- Java提高篇(二八)------TreeSet
- Java提高篇(二八)------TreeSet
- java中如果想要去重且排序用TreeSet
- Java提高 - 八大排序方法之其他算法
- Java提高篇(二八)------TreeSet
- java程序员从笨鸟到菜鸟之(二十八)集合TreeSet排序之compareTo和compare方法
- Java_基础—TreeSet保证元素唯一和自然排序
- java集合TreeSet的两种排序方式
- Java:TreeSet定制排序后无法被对象输出流写入到文件