TreeSet(一)–排序

  • Post author:
  • Post category:其他




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

方法










People对象











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






去掉people中注解,运行结果:






















(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;	
	}	
}

最后输出结果:






       /**
	 * 是不是很奇怪为什么只有五条数据,而不是六条,那是因为有一条数据被覆盖了。
	 * 你的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】



























































版权声明:本文为yudiandemingzi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。