方法1:自然排序(实现comparable接口compareto方法)
方法2:自定义排序(Comparator接口、compare方法)
一、自然排序
1、Comparable是在集合内部定义的方法实现的排序,位于java.util下。
2、如果创建一个集合来储存对象,当存储的对象是Integer类型、String类型时,因为这些类型已经实现了Comparable接口. 所以遍历输出这个集合时会按照这些类的重写的compareTo()方法来顺序输出。List<String> list1 = new ArrayList<>();
3、如果我们想要排序一个自定义类,或者让一个自定义类可以比较大小就需要该类实现Comparable接口,重写compareto()方法。
4、TreeSet类的排序
1 package text; 2 3 4 5 import java.util.Iterator; 6 7 import java.util.Set; 8 9 import java.util.TreeSet; 10 11 12 13 public class Main { 14 15 16 17 public static void main(String[] args) { 18 19 Set set = new TreeSet(); 20 21 People p1 = new People(1, 18,"小明"); 22 23 People p2 = new People(2, 5,"大壮"); 24 25 People p3 = new People(3, 20,"小红"); 26 27 28 29 set.add(p1); 30 31 set.add(p2); 32 33 set.add(p3); 34 35 36 37 Iterator it=set.iterator(); 38 39 while(it.hasNext()){ 40 41 System.out.println(it.next()); 42 43 } 44 45 } 46 47 48 49 } 50 51 52 53 package text; 54 55 56 57 public class People implements Comparable{ 58 59 int id; 60 61 int age; 62 63 String name; 64 65 66 67 public People(int id, int age, String name) { 68 69 super(); 70 71 this.id = id; 72 73 this.age = age; 74 75 this.name = name; 76 77 } 78 79 80 81 @Override 82 83 public String toString() { 84 85 return "people [id=" + id + ", age=" + age + ", name=" + name + "]"; 86 87 } 88 89 90 91 92 93 @Override 94 95 public int compareTo(Object o) { 96 97 People p; 98 99 if(o instanceof People){ 100 101 p = (People)o; 102 103 }else{ 104 105 return -1; 106 107 } 108 109 int diff = this.age - p.age; 110 111 if(diff!=0){ 112 113 diff = diff / Math.abs(diff); 114 115 } 116 117 return diff; 118 119 } 120 121 122 123 124 125 }
5、HashSet
(1)HashSet类的使用,不支持对元素数据进行排序
(2)即使自定义的类实现了comparable接口,但是结果还是不排序
6、ArrayList的排序(LInkedList的排序类似)
1 package com.xykj.comparable; 2 3 public class User implements Comparable 4 5 6 7 {//这里的User是后面集合类的泛型 8 9 String name = ""; 10 11 String password = ""; 12 13 public User(String name, String password) { 14 15 this.name = name; 16 17 this.password = password; 18 19 } 20 21 // 实现排序必须要重写的方法 22 23 @Override 24 25 public int compareTo(User o) {//按照密码的升序排列,想要按照名字排序就把password换成name就可以了 26 27 return password.compareTo(o.password); 28 29 } 30 31 // 重写toString方法 32 33 @Override 34 35 public String toString() { 36 37 return name + " " + password; 38 39 } 40 41 } 42 43 44 45 46 47 package com.xykj.comparable; 48 import java.util.ArrayList; 49 50 import java.util.Collections; 51 52 public class ArrayListTest { 53 54 //对ArrayList排序必须要使用Collections.sort(list),否则不会排序, 55 56 //会按照添加的顺序打印出来 57 58 public static void main(String[] args) { 59 60 ArrayList 61 62 63 64 list = new ArrayList<>(); 65 66 for (int i = 1; i <= 10; i++) { 67 68 list.add(new User("ArrayList_name" + i, " ArrayList_password" + (50 - i))); 69 70 } 71 72 Collections.sort(list);//如果注释后,输入输出不改变 73 74 for (User user : list) { 75 76 System.out.println(user.toString()); 77 78 } 79 80 } 81 82 }
结果:
升序输入,降序输出
二、自定义排序
1、Comparator是在集合外部实现的排序,位于java.lang下,是一个专用的比较器。当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。
2、Comparator体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。使用方法只能用Collections类的sort方法,并且是传递两个参数进去(List list,Class class),第一个参数是集合的对象list,第二个是实现了comparator接口的实现类的对象。
3、 功能:按照存储的对象的某个属性排列来显示该对象的所有属性,只能对任意集合List接口下的实现类ArrayList和LinkedList进行排序
4、使用方法:
(1)需要在另一个类是实现Comparator,同样后面也要加泛型,这个泛型是需要排序的自定义类
(2)要重写compare方法,比较Object里面的具体属性用compareTo
(3)需要Collections工具类的sort方法,方法里面传入两个参数:第一个参数是列表信息list,第二个参数是实现了comparator的类的对象
5.Comparator的示例
(1)先建一个基本属性类
1 package com.xykj.comparatorTest; 2 3 public class Student { 4 5 //创建两个基本属性 6 7 String name=""; 8 9 int age=0; 10 11 12 13 //从写构造方法用来传递数据 14 15 public Student(String name, int age) { 16 17 super(); 18 19 this.name = name; 20 21 this.age = age; 22 23 } 24 25 //从写toString方法,方便显示 26 27 @Override 28 29 public String toString() { 30 31 return name + " " + age ; 32 33 } 34 35 36 37 //基本属性的get和set方法 38 39 public String getName() { 40 41 return name; 42 43 } 44 45 public void setName(String name) { 46 47 this.name = name; 48 49 } 50 51 public int getAge() { 52 53 return age; 54 55 } 56 57 public void setAge(int age) { 58 59 this.age = age; 60 61 } 62 63 64 65 } 66 67
(2)创建按照姓名升序排列的实现类
1 package com.xykj.comparatorTest; 2 3 4 5 import java.util.Comparator; 6 7 //按照名字的升序排列 实现接口 泛型是自定义类,里面有要排序的内容 8 9 public class NameSort implements Comparator 10 11 12 13 { 14 15 @Override //两个参数是泛型的对象 16 17 public int compare(Student o1, Student o2) { 18 19 //按照姓名的升序排列,前面加个负号就按照降序排列 20 21 return o1.getName().compareTo(o2.getName()); 22 23 } 24 25 } 26 27
(3)创建按照年龄升序排列的实现类
1 package com.xykj.comparatorTest; 2 3 import java.util.Comparator; 4 5 //按照年龄的升序排列 实现接口 泛型是自定义类,里面有要排序的内容 6 7 public class AgeSort implements Comparator 8 9 10 11 { 12 13 14 15 @Override //两个参数是泛型的对象 16 17 public int compare(Student o1, Student o2) { 18 19 //按照姓名的升序排列,前面加个负号就按照降序排列 20 21 return o1.getAge()-o2.getAge(); 22 23 } 24 25 }
(4)对ArrayList进行排序
1 package com.xykj.comparatorTest; 2 3 import java.util.ArrayList; 4 5 import java.util.Collections; 6 7 public class MainClass { 8 9 /** 10 11 * comparator的使用 12 13 * */ 14 15 public static void main(String[] args) { 16 17 ArrayList 18 19 20 21 list = new ArrayList<>(); 22 23 list.add(new Student("1wenzhi", 18)); 24 25 list.add(new Student("3wenzhi", 19)); 26 27 list.add(new Student("2wenzhi", 33)); 28 29 list.add(new Student("66wenzhi", 10)); 30 31 list.add(new Student("4wenzhi", 18)); 32 33 System.out.println("=========排序前======="); 34 35 for (Student student : list) { 36 37 System.out.println(student); 38 39 } 40 41 42 43 // 按照年龄升序排列 44 45 Collections.sort(list, new AgeSort()); 46 47 System.out.println("=========排序后======="); 48 49 50 51 for (Student student : list) { 52 53 System.out.println(student); 54 55 } 56 57 } 58 59 }
结果
可以看到添加数乱序添加的,正常打印是按照添加的顺序打印的,排序后就可以得到想要的
Collections.sort方法只能对List接口下的实现类进行排序,对Set接口下的实现类不能进行排序