TreeSet的两种排序方式

1.排序的引入

由于TreeSet可以实现对元素按照某种规则进行排序,例如下面的例子
public class TreeSetDemo {
	public static void main(String[] args) {
		// 创建集合对象
		// 自然顺序进行排序
		TreeSet ts = new TreeSet();

		// 创建元素并添加
		// 20,18,23,22,17,24,19,18,24
		ts.add(20);
		ts.add(18);
		ts.add(23);
		ts.add(22);
		ts.add(17);
		ts.add(24);
		ts.add(19);
		ts.add(18);
		ts.add(24);

		// 遍历
		for (Integer i : ts) {
			System.out.println(i);
		}
	}
}

运行结果为:
TreeSet的两种排序方式_第1张图片

但是对自定义对象呢?
public class TreeSetDemo02 {
	public static void main(String[] args) {
		TreeSet ts=new TreeSet();		
		//创建元素对象
		Student s1=new Student("zhangsan",20);
		Student s2=new Student("lis",22);
		Student s3=new Student("wangwu",24);
		Student s4=new Student("chenliu",26);
		Student s5=new Student("zhangsan",22);
		Student s6=new Student("qianqi",24);
		
		//将元素对象添加到集合对象中
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		
		//遍历
		for(Student s:ts){
			System.out.println(s.getName()+"-----------"+s.getAge());
		}
	}
}
Student类:
public class Student {
	private String name;
	private int age;
	
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}	

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}



运行结果:

原因分析:
由于不知道该安照那一中排序方式排序,所以会报错。

解决方法:
   1.自然排序
2.比较器排序


2.自然排序

自然排序要进行一下操作:

1.Student类中实现  Comparable接口
2.重写Comparable接口中的Compareto方法

 int compareTo(T o)
          比较此对象与指定对象的顺序。

故Student类为: 特别注意在重写Compareto方法时,注意排序 


package xfcy_04;
/**
 * Student类
 * @author 晓风残月
 *
 */
public class Student implements Comparable {
	private String name;
	private int age;
	
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}	

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public int compareTo(Student s) {
		//return -1; //-1表示放在红黑树的左边,即逆序输出
		//return 1;  //1表示放在红黑树的右边,即顺序输出
		//return o;  //表示元素相同,仅存放第一个元素
		//主要条件 姓名的长度,如果姓名长度小的就放在左子树,否则放在右子树
		int num=this.name.length()-s.name.length();  
		//姓名的长度相同,不代表内容相同,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。
		//如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。
		//如果这两个字符串相等,则结果为 0
		int num1=num==0?this.name.compareTo(s.name):num;
		//姓名的长度和内容相同,不代表年龄相同,所以还要判断年龄
		int num2=num1==0?this.age-s.age:num1;
		return num2;
	}
	
}


而主类中为:
package xfcy_04;

import java.util.TreeSet;

/*
* TreeSet存储自定义对象并保证排序和唯一。
 * 
 * 需求:请按照姓名的长度排序
 */
public class TreeSetDemo02 {
	public static void main(String[] args) {
		//创建集合对象		
		TreeSet ts=new TreeSet();

		
		//创建元素对象
		Student s1=new Student("zhangsan",20);
		Student s2=new Student("lis",22);
		Student s3=new Student("wangwu",24);
		Student s4=new Student("chenliu",26);
		Student s5=new Student("zhangsan",22);
		Student s6=new Student("qianqi",24);
		
		//将元素对象添加到集合对象中
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		
		//遍历
		for(Student s:ts){
			System.out.println(s.getName()+"-----------"+s.getAge());
		}
	}
}


运行结果:
TreeSet的两种排序方式_第2张图片

3、比较器排序

比较器排序步骤:
1.单独创建一个比较类,这里以MyComparator为例,并且要让其继承Comparator接口
2.重写Comparator接口中的Compare方法
 int compare(T o1,T o2)
          比较用来排序的两个参数。

3.在主类中使用下面的 构造方法

TreeSet(Comparator comparator)
          构造一个新的空 TreeSet,它根据指定比较器进行排序。

          
主类:

package xfcy_04;

import java.util.TreeSet;

/*
* TreeSet存储自定义对象并保证排序和唯一。
 * 
 * 需求:请按照姓名的长度排序
 */
public class TreeSetDemo02 {
	public static void main(String[] args) {
		//创建集合对象
		//TreeSet(Comparator comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。
		TreeSet ts=new TreeSet(new MyComparator());

		//创建元素对象
		Student s1=new Student("zhangsan",20);
		Student s2=new Student("lis",22);
		Student s3=new Student("wangwu",24);
		Student s4=new Student("chenliu",26);
		Student s5=new Student("zhangsan",22);
		Student s6=new Student("qianqi",24);
		
		//将元素对象添加到集合对象中
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		
		//遍历
		for(Student s:ts){
			System.out.println(s.getName()+"-----------"+s.getAge());
		}
	}
}


MyComparator类:
package xfcy_04;

import java.util.Comparator;

public class MyComparator implements Comparator{

	@Override
	public int compare(Student s1,Student s2) {
		// 姓名长度
		int num = s1.getName().length() - s2.getName().length();
		// 姓名内容
		int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
		// 年龄
		int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
		return num3;
	}
	
	
	
	
}

学生类(不需要继承Comparetable接口)
package xfcy_04;
/**
 * Student类
 * @author 晓风残月
 *
 */
public class Student{
	private String name;
	private int age;
	
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}	

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
}


运行结果:

TreeSet的两种排序方式_第3张图片



4.比较器修改


由于单独创建一个类不是特别好,因而可以将MyComparetor的内容直接写到主类中

public class TreeSetDemo {
        public static void main(String[] args) {
                // 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象
		// 而匿名内部类就可以实现这个东西
		TreeSet ts = new TreeSet(new Comparator() {
			@Override
			public int compare(Student s1, Student s2) {
				// 姓名长度
				int num = s1.getName().length() - s2.getName().length();
				// 姓名内容
				int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
						: num;
				// 年龄
				int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
				return num3;
			}
		});

		// 创建元素
		Student s1 = new Student("linqingxia", 27);
		Student s2 = new Student("zhangguorong", 29);
		Student s3 = new Student("wanglihong", 23);
		Student s4 = new Student("linqingxia", 27);
		Student s5 = new Student("liushishi", 22);
		Student s6 = new Student("wuqilong", 40);
		Student s7 = new Student("fengqingy", 22);
		Student s8 = new Student("linqingxia", 29);

		// 添加元素
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		ts.add(s7);
		ts.add(s8);

		// 遍历
		for (Student s : ts) {
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}


运行结果也如同上面一样

5.总结

A:自然排序:要在自定义类中实现Comparerable接口  ,并且重写compareTo方法
B:比较器排序:在自定义类中实现Comparetor接口,重写compare方法
















你可能感兴趣的:(Java)