树形结构集合中(TreeMap和TreeSet)的自然排序和比较器排序
在树形结构的集合TreeMap和TreeSet中,数据的存储的顺序和用put方法放进去的顺序是不一定相同的,因为树形结构的数据存储是根据红黑树的计算结果进行存储的,所以在我们用树形结构集合存储一个指定类型时:那么就需要给这个类型(也就是这个类)指定相应的排序规则(这个排序规则就是红黑树的计算排序法则),指定规则的方式有两种:
一,自然排序
如果我们用树形结构的集合存储一个类时:比如:TreeSet<Student> treeSet=new TreeSet;
那么我们使用自然排序的话就需要让Student类实现Comparable<>接口(并且记得接口后面的泛型是实现类的类的类型在这类也就是Student),然后重写里面的compareTo方法就行了:
假如一个TreeSet集合存储Student类:
1 package com.heima.work.demo; 2 3 public class Student implements Comparable<Student> { 4 private String name; 5 private int age; 6 7 public Student() { 8 } 9 10 public Student(String name, int age) { 11 this.name = name; 12 this.age = age; 13 } 14 15 public String getName() { 16 return name; 17 } 18 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 public int getAge() { 24 return age; 25 } 26 27 public void setAge(int age) { 28 this.age = age; 29 } 30 31 @Override 32 public String toString() { 33 return "Student{" + 34 "name='" + name + '\'' + 35 ", age=" + age + 36 '}'; 37 } 38 39 @Override 40 public int compareTo(Student o) { 41 return this.age - o.age;//这是对方法的重写年龄从小到大 42 } 43 }
测试类为:
1 package com.heima.work.demo; 2 3 import java.util.TreeSet; 4 5 public class demo01 { 6 public static void main(String[] args) { 7 TreeSet<Student> treeSet = new TreeSet<>(); 8 treeSet.add(new Student("张三", 23)); 9 treeSet.add(new Student("李四", 24)); 10 treeSet.add(new Student("王五", 26)); 11 treeSet.add(new Student("张三", 28)); 12 13 System.out.println(treeSet); 14 15 16 } 17 18 19 }
结果是:
如果我们改变排序规则,即:
1 package com.heima.work.demo; 2 3 public class Student implements Comparable<Student> { 4 private String name; 5 private int age; 6 7 public Student() { 8 } 9 10 public Student(String name, int age) { 11 this.name = name; 12 this.age = age; 13 } 14 15 public String getName() { 16 return name; 17 } 18 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 public int getAge() { 24 return age; 25 } 26 27 public void setAge(int age) { 28 this.age = age; 29 } 30 31 @Override 32 public String toString() { 33 return "Student{" + 34 "name='" + name + '\'' + 35 ", age=" + age + 36 '}'; 37 } 38 39 @Override 40 public int compareTo(Student o) { 41 return o.age - this.age;//改变排序规则,从大到小 42 } 43 }
结果为:
第二种:比较器排序
自然排序是在指定类中让其实现类继承Comparabale接口但是如果我们有树形集合存储的数据类型我们我发修改或者说让它实现Comparabale接口呢?比如说String类,这是java已经封账好的类,我们无法对他进行自然排序的修改,针对这种情况有了第二种排序的方法:比较器排序
比较器排序是在树形集合的构造方法中重写Comparator<T>接口:
例子:
1 package com.heima.work.demo; 2 3 import java.util.Comparator; 4 import java.util.TreeSet; 5 6 public class demo002 { 7 public static void main(String[] args) { 8 TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {//这里就是比较器 9 @Override 10 public int compare(Student o1, Student o2) { 11 return o1.getAge() - o2.getAge(); 12 13 } 14 }); 15 treeSet.add(new Student("张三", 23)); 16 treeSet.add(new Student("李四", 24)); 17 treeSet.add(new Student("王五", 26)); 18 treeSet.add(new Student("张三", 28)); 19 20 System.out.println(treeSet); 21 22 23 } 24 }
结果是:
如果我们改变比较规则,即改变第11行代码的顺序:
1 package com.heima.work.demo; 2 3 import java.util.Comparator; 4 import java.util.TreeSet; 5 6 public class demo002 { 7 public static void main(String[] args) { 8 TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() { 9 @Override 10 public int compare(Student o1, Student o2) { 11 return o2.getAge()-o1.getAge();//这里已经改变了顺序 12 13 } 14 }); 15 treeSet.add(new Student("张三", 23)); 16 treeSet.add(new Student("李四", 24)); 17 treeSet.add(new Student("王五", 26)); 18 treeSet.add(new Student("张三", 28)); 19 20 System.out.println(treeSet); 21 22 23 } 24 }
结果是:
总结就是优先选择自然排序,在自然排序行不通的情况下使用比较器排序
迎风少年