浅谈JavaTreeSet集合

Java中TreeSet集合也是Set集合的一种。

其特点是唯一,有序。

TreeSet集合的排序方式有两种:

A:自然排序

B:比较器排序

1.自然排序

TreeSet<Student> st=new TreeSet<Student>();

TreeSet的无参构造默认其排序方式是自然排序,实现方法如下:

package Test1;

import java.util.TreeSet;

import Test2.Student;
/*
 * TreeSet<Student> st=new TreeSet<Student>();
 * 这是无参构造,默认为自然排序,所以Student类需要实现Comparable<Student>接口
 * 
 * 按照年龄排序
 */
public class TreeSetDemo {
	public static void main(String[] args) {
		TreeSet<Student> st=new TreeSet<Student>();
		
		Student s1=new Student("小明", 22);
		Student s2=new Student("小红", 30);
		Student s3=new Student("小刚", 20);
		Student s4=new Student("小李", 30);
		Student s5=new Student("小王", 24);
		Student s6=new Student("小明", 22);
		Student s7=new Student("小智", 22);
		
		
		st.add(s1);
		st.add(s2);
		st.add(s3);
		st.add(s4);
		st.add(s5);
		st.add(s6);
		st.add(s7);
		
		for(Student s:st) {
			System.out.println(s.getName()+"---"+s.getAge());
		}
	}
}


package Test1;

public class Student implements Comparable<Student>{
	private String name;
	private int age;
	public Student(String name, int age) {
		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) { 
                 //判断年龄
		int num=this.age-s.age;
		//判断姓名
		//compareTo() 字符串比较,如果相同返回0
		//如果num等于0(说明年龄相同),就比较姓名
		int num2=num==0?this.name.compareTo(s.name):num;
		return num2;
	}
	
}

需要注意的是在Student类中需要实现接口 Comparable<Student>的compareTo()方法,在实现过程中要注意主要排序规则和次要排序规则都要判断。比如这里的主要排序规则是年龄,但是姓名也是需要进行判断的。

2.比较器排序

TreeSet<Student> st=new TreeSet<Student>(new MyComparator());

比较器排序采用带参构造,其参数是对象,较自然排序而言稍微复杂了一点。

实现方法如下:

package Test2;

import java.util.Comparator;
import java.util.TreeSet;

/*
 * 按照姓名长度排序
 *
 * 比较器排序
 */

public class TreeSetDemo {
	public static void main(String[] args) {
		
		//TreeSet<Student> st=new TreeSet<Student>();
		TreeSet<Student> st=new TreeSet<Student>(new MyComparator());
		
		Student s1=new Student("xiaoming", 22);
		Student s2=new Student("xiaomei", 30);
		Student s3=new Student("xiaogang", 20);
		Student s4=new Student("xiaoli", 30);
		Student s5=new Student("xiaowang", 24);
		Student s6=new Student("xiaoming", 22);
		Student s7=new Student("xiaozhi", 22);
		
		
		st.add(s1);
		st.add(s2);
		st.add(s3);
		st.add(s4);
		st.add(s5);
		st.add(s6);
		st.add(s7);
		
		for(Student s:st) {
			System.out.println(s.getName()+"---"+s.getAge());
		}
	}
}

package Test2;

public class Student{
	private String name;
	private int age;
	public Student(String name, int age) {
		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;
	}
}

package Test2;

import java.util.Comparator;

public class MyComparator implements Comparator<Student>{

	@Override
        //在自然排序中,因为Student中有this表示当前的对象,所以在
        //compareTo()方法中只有一个参数,但是在这里因为没有this,所以要有两个参数
	public int compare(Student s1, Student s2) {
		//判断姓名长度
		//因为在Student类中成员变量是private,所以不能直接访问
		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;
	}
	
}

在这里Students类不需要在实现 Comparator<Student>接口,但是需要再写一个类MyComparator,在这个类中实现compare()方法,以此实现排序。那么问题来了,如果使用比较器排序,还需要再写一个类,较自然排序就要麻烦一点,那我们为什么要使用比较器排序呢?

其实在开发过程中,比较器排序还是比较常用的,因为它还有另外一种写法。

package Test2;

import java.util.Comparator;
import java.util.TreeSet;

/*
 * 按照姓名长度排序
 * 
 * 比较器排序
 */

public class TreeSetDemo {
	public static void main(String[] args) {
		
		//TreeSet<Student> st=new TreeSet<Student>();
		
		//如果一个方法的参数是接口,那么真正要的是接口实现类的对象
		//而匿名内部类就可以实现这个东西
		TreeSet<Student> st=new TreeSet<Student>(new Comparator<Student>() {
			public int compare(Student s1, Student s2) {
				//判断姓名长度
				//因为在Student类中成员变量是private,所以不能直接访问
				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("xiaoming", 22);
		Student s2=new Student("xiaomei", 30);
		Student s3=new Student("xiaogang", 20);
		Student s4=new Student("xiaoli", 30);
		Student s5=new Student("xiaowang", 24);
		Student s6=new Student("xiaoming", 22);
		Student s7=new Student("xiaozhi", 22);
		
		
		st.add(s1);
		st.add(s2);
		st.add(s3);
		st.add(s4);
		st.add(s5);
		st.add(s6);
		st.add(s7);
		
		for(Student s:st) {
			System.out.println(s.getName()+"---"+s.getAge());
		}
	}
}

使用匿名内部类直接实现排序,当排序方式改变时,只需要在造对象时直接实现就可以了,不需要在改别的代码 ,这样就大大的提高了程序的灵活性,更贴合面向对象的思想。

发布了88 篇原创文章 · 获赞 47 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/dai_ma_dong/article/details/103166748