TreeSet集合及构造器排序和自然排序详解和特点

1.TreeSet集合特点

  • 元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法
    TreeSet():根据其元素的自然排序进行排序
    TreeSet(Comparator comparator):根据指定的比较器进行排序
  • 没有带索引的方法,所以不能使用普通for循环遍历
  • 由于是Set集合,所以不包含重复元素的集合

不同构造方法的排序

1.无参构造方法(默认构造方法)

按元素的自然排序,由小到大

public static void main(String[] args) {
		//创建集合对象
		TreeSet<Integer> ts=new TreeSet<Integer>();
		//添加元素
		ts.add(90);
		ts.add(50);
		ts.add(70);
		
		for(Integer i:ts) {
			System.out.println(i);
		}
		
	}

控制台结果:

JAVA的TreeMap的排序规则 treeset排序_算法

2.自然排序Comparable的使用

  • 存储学生对象并遍历,创建TreeSet集合使用无参构造方法
  • 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

学生类 实现Comparable接口,改写compareTo()方法

public class Student implements Comparable<Student> {
	private String name;
	private int age;

	public Student() {
	}

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

	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 0; 每次比较返回0只添加第一个元素,其余元素会被认为是重复元素不添加
		//return 1;返回正数按照升序存储
		//return -1; 返回负数按照降序存储
		
		//按照年龄从小到大排序
		//当前年龄和传入对象年龄比较
		int num=this.age-s.age;
		//若年龄相同比较姓名
		int res=num==0?this.name.compareTo(s.name):num;
		return res;
	}
}

测试类

public static void main(String[] args) {
		TreeSet<Student> ts=new TreeSet<Student>();
		Student s1=new Student("tom", 20);
		Student s2=new Student("lucy",21);
		Student s3=new Student("luna", 22);
		Student s4=new Student("anna", 20);
		
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		
		for (Student s : ts) {
			System.out.println(s.getName()+":"+s.getAge());
		}
	}

控制台结果

JAVA的TreeMap的排序规则 treeset排序_算法_02

2.结论

  • 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
  • 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
  • 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

3.比较器排序Comparator的使用

  • 存储学生对象并遍历,创建TreeSet集合使用带参构造方法
  • 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

学生类-没有实现Comparable接口

public class Student {
	private String name;
	private int age;

	public Student() {
	}

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

	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对象时传入Comparator对象,实现接口方法

public static void main(String[] args) {
		TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {

			@Override
			public int compare(Student s1, Student s2) {
				int num=s1.getAge()-s2.getAge();  //比较年龄
				int res=num==0?s1.getName().compareTo(s2.getName()):num; //比较姓名
				return res;
			}
			
		});
		
		Student s1=new Student("tom", 20);
		Student s2=new Student("lucy",21);
		Student s3=new Student("luna", 22);
		Student s4=new Student("anna", 20);
		
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		
		for (Student s : ts) {
			System.out.println(s.getName()+":"+s.getAge());
		}
		
	}

结论

  • 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
  • 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T t1,T t2)方法
  • 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写