TreeSet的两种排序方式

xiaoxiao2021-02-28  138

TreeSet的两种排序方式

1.排序的引入

由于TreeSet可以实现对元素按照某种规则进行排序,例如下面的例子 [java] view plain copy print ? public class TreeSetDemo {      public static void main(String[] args) {          // 创建集合对象          // 自然顺序进行排序          TreeSet<Integer> ts = new TreeSet<Integer>();            // 创建元素并添加          // 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);          }      }  }   public class TreeSetDemo { public static void main(String[] args) { // 创建集合对象 // 自然顺序进行排序 TreeSet<Integer> ts = new TreeSet<Integer>(); // 创建元素并添加 // 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); } } } 运行结果为: 但是对自定义对象呢? [java] view plain copy print ? public class TreeSetDemo02 {      public static void main(String[] args) {          TreeSet<Student> ts=new TreeSet<Student>();               //创建元素对象          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());          }      }  }   public class TreeSetDemo02 { public static void main(String[] args) { TreeSet<Student> ts=new TreeSet<Student>(); //创建元素对象 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类: [java] view plain copy print ? 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;      }  }   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<T>接口 2.重写Comparable接口中的Compareto方法  intcompareTo(T o)           比较此对象与指定对象的顺序。 故Student类为: 特别注意在重写Compareto方法时,注意排序  [java] view plain copy print ? package xfcy_04;  /**  * Student类  * @author 晓风残月  *  */  public class Student implements Comparable<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;      }        @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; /** * Student类 * @author 晓风残月 * */ public class Student implements Comparable<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; } @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; } } 而主类中为: [java] view plain copy print ? package xfcy_04;    import java.util.TreeSet;    /* * TreeSet存储自定义对象并保证排序和唯一。  *   * 需求:请按照姓名的长度排序  */  public class TreeSetDemo02 {      public static void main(String[] args) {          //创建集合对象                  TreeSet<Student> ts=new TreeSet<Student>();                      //创建元素对象          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());          }      }  }   package xfcy_04; import java.util.TreeSet; /* * TreeSet存储自定义对象并保证排序和唯一。 * * 需求:请按照姓名的长度排序 */ public class TreeSetDemo02 { public static void main(String[] args) { //创建集合对象 TreeSet<Student> ts=new TreeSet<Student>(); //创建元素对象 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()); } } } 运行结果:

3、比较器排序

比较器排序步骤: 1.单独创建一个比较类,这里以MyComparator为例,并且要让其继承Comparator<T>接口 2.重写Comparator接口中的Compare方法  intcompare(T o1,T o2)           比较用来排序的两个参数。 3.在主类中使用下面的 构造方法 TreeSet(Comparator<? superE> comparator)           构造一个新的空 TreeSet,它根据指定比较器进行排序。            主类: [java] view plain copy print ? package xfcy_04;    import java.util.TreeSet;    /* * TreeSet存储自定义对象并保证排序和唯一。  *   * 需求:请按照姓名的长度排序  */  public class TreeSetDemo02 {      public static void main(String[] args) {          //创建集合对象          //TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。          TreeSet<Student> ts=new TreeSet<Student>(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());          }      }  }   package xfcy_04; import java.util.TreeSet; /* * TreeSet存储自定义对象并保证排序和唯一。 * * 需求:请按照姓名的长度排序 */ public class TreeSetDemo02 { public static void main(String[] args) { //创建集合对象 //TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。 TreeSet<Student> ts=new TreeSet<Student>(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类: [java] view plain copy print ? package xfcy_04;    import java.util.Comparator;    public class MyComparator implements Comparator<Student>{        @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;      }                          }   package xfcy_04; import java.util.Comparator; public class MyComparator implements Comparator<Student>{ @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接口) [java] view plain copy print ? 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;      }        }   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; } } 运行结果:

4.比较器修改

由于单独创建一个类不是特别好,因而可以将MyComparetor的内容直接写到主类中 [java] view plain copy print ? public class TreeSetDemo {          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.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());          }      }  }   public class TreeSetDemo { 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.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<T>接口  ,并且重写compareTo方法

B:比较器排序:在自定义类中实现Comparetor<t>接口,重写

原文链接:http://blog.csdn.net/xiaofei__/article/details/53138681

转载请注明原文地址: https://www.6miu.com/read-25808.html

最新回复(0)