Java Collection - 002 排序
第一种,可以实现边添加边排序,需要用到TreeSet。
第二种,用数组存放对象们,但是不需单独取出某属性排列好再重存,而是在原数组上用比较器重新排一次序。需要用到Arrays.sort(arr,comparator)。
第三种,用集合类中的list的子类存放对象们,然后排序。需要用到Collections.sort(list,comparator)。
java常用类实现Comparable接口,并提供了比较大小的标准。实现Comparable接口的常用类:
- BigDecimal、BigIneger以及所有数值型对应包装类:按它们对应的数值的大小进行比较。
- Character:按字符的UNICODE值进行比较。
- Boolean:true对应的包装类实例大于false对应的包装类实例。
- String:按字符串中字符的UNICODE值进行比较。
- Date、Time:后面的时间、日期比前面的时间、日期大。
一般默认排序是升序,也就是自然排序
1.TreeSet排序:
/*
* TreeSet存储对象的时候, 可以排序, 但是需要指定排序的算法
*
* Integer能排序(有默认顺序), String能排序(有默认顺序), 自定义的类存储的时候出现异常(没有顺序)
*
* 如果想把自定义类的对象存入TreeSet进行排序, 那么必须实现Comparable接口
* 在类上implement Comparable
* 重写compareTo()方法
* 在方法内定义比较算法, 根据大小关系, 返回正数负数或零
* 在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较, 根据比较结果使用二叉树形式进行存储
*/
2.TreeSet是依靠TreeMap来实现的。
TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列. 基本封装类型以及实现了Comparable接口,可以直接添加排序。如Integer, String类型
1 import java.util.Iterator; 2 import java.util.*; 3 4 public class TreeSetTest { 5 public static void main(String[] args) { 6 Set ts = new TreeSet(); 7 ts.add("abc"); 8 ts.add("xyz"); 9 ts.add("rst"); 10 Iterator it = ts.iterator(); 11 while (it.hasNext()) { 12 System.out.println(it.next()); 13 } 14 } 15 }
输出结果:
abc
rst
xyz
打印结果不是和先前加入的顺序一样,它是按照一个字母的排序法进行排序的。这是因为String 类实现了Comparable接口。
By default, String object (name) in TreeSet will be displayed in ascending order. if you want them displayed in descending order, you just need to
You just need to instantiate the TreeSet with
1 new TreeSet<>(Collections.reverseOrder());
This is a Comparator which reverses the natural order of the objects.
2.TreeSet对自定义对象的排序
2.1 使用TreeSet()构造方法,并对需要添加到set集合中的元素实现Comparable接口进行排序;
如果我们自己定义的一个类的对象要加入到TreeSet当中,那么这个类必须要实现Comparable接口。
1 package test.treeset; 2 import java.util.Iterator; 3 import java.util.Set; 4 import java.util.TreeSet; 5 6 7 public class test_treeset { 8 @SuppressWarnings("unchecked") 9 public static void main(String[] args) { 10 Set ts = new TreeSet(); 11 ts.add(new Teacher("zhangsan", 1)); 12 ts.add(new Teacher("lisi", 2)); 13 ts.add(new Teacher("wangmazi", 3)); 14 ts.add(new Teacher("wangwu",4)); 15 ts.add(new Teacher("mazi", 3)); 16 Iterator it = ts.iterator(); 17 while (it.hasNext()) { 18 System.out.println(it.next()); 19 } 20 } 21 } 22 class Teacher implements Comparable { 23 int num; 24 String name; 25 26 Teacher(String name, int num) { 27 this.num = num; 28 this.name = name; 29 } 30 31 public String toString() { 32 return "学号:" + num + "\t\t姓名:" + name; 33 } 34 35 //o中存放时的红黑二叉树中的节点,从根节点开始比较 36 public int compareTo(Object o) { 37 Teacher ss = (Teacher) o; 38 int result = num < ss.num ? 1 : (num == ss.num ? 0 : -1);//降序 39 //int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1);//升序 40 if (result == 0) { 41 result = name.compareTo(ss.name); 42 } 43 return result; 44 } 45 }
运行结果:
学号:4 姓名:wangwu
学号:3 姓名:mazi
学号:3 姓名:wangmazi
学号:2 姓名:lisi
学号:1 姓名:zhangsan
2.2. 通过TreeSet(Comparator<? super E> comparator) 构造方法指定TreeSet的比较器进行排序;
在使用Arrays对数组中的元素进行排序的时候,可以传递一个比较器。
在使用Collections对集合中的元素进行排序的时候,可以传递一个比较器。
那么在使用TreeSet对加入到其中的元素进行排序的时候可以传入一个比较器吗?
1 public TreeSet(Comparator<? super E> comparator) { 2 this(new TreeMap<E,Object>(comparator)); 3 }
通过查看它的构造方法就知道可以传入一个比较器。
构造一个新的空TreeSet,它根据指定比较器进行排序。插入到该 set 的所有元素都必须能够由指定比较器进行相互比较:对于 set 中的任意两个元素 e1 和e2,执行 comparator.compare(e1, e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set 中,则 add 调用将抛出 ClassCastException。
1 package test.treeset; 2 3 import java.util.Comparator; 4 import java.util.Iterator; 5 import java.util.TreeSet; 6 7 public class TreeSetTest { 8 @SuppressWarnings("unchecked") 9 public static void main(String[] args) { 10 TreeSet ts = new TreeSet(new Teacher2.TeacherCompare()); 11 ts.add(new Teacher2("zhangsan", 2)); 12 ts.add(new Teacher2("lisi", 1)); 13 ts.add(new Teacher2("wangmazi", 3)); 14 ts.add(new Teacher2("mazi", 3)); 15 Iterator it = ts.iterator(); 16 while (it.hasNext()) { 17 System.out.println(it.next()); 18 } 19 } 20 } 21 22 class Teacher2 { 23 int num; 24 String name; 25 26 Teacher2(String name, int num) { 27 this.num = num; 28 this.name = name; 29 } 30 31 public String toString() { 32 return "学号:" + num + " 姓名:" + name; 33 } 34 35 static class TeacherCompare implements Comparator {// 老师自带的一个比较器 36 //o1中存放的事目标节点 37 //o2中存放时的红黑二叉树中的节点,从根节点开始比较 38 public int compare(Object o1, Object o2) { 39 Teacher2 s1 = (Teacher2) o1;// 转型 40 Teacher2 s2 = (Teacher2) o2;// 转型 41 int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1); 42 if (result == 0) { 43 result = s1.name.compareTo(s2.name); 44 } 45 return result; 46 } 47 48 } 49 50 }
运行结果:
学号:1 姓名:lisi
学号:2 姓名:zhangsan
学号:3 姓名:mazi
学号:3 姓名:wangmazi
二、用数组存放对象,用比较器改变sort()排序方法。
数组本身有默认的排序方法,针对int、string等基本类型有默认的sort()方法。而针对类对象的排序,可以给sort()方法传进一个比较器对象,赋予其排序的算法。
1 public class ArraysTest { 2 3 public static void main(String[] args) { 4 Person[] people = new Person[5]; 5 people[0] = (new Person("小明", 20)); 6 people[1] = (new Person("小张", 30)); 7 people[2] = (new Person("小刘", 18)); 8 people[3] = (new Person("小林", 17)); 9 people[4] = (new Person("小刘", 35)); 10 11 Arrays.sort(people, new MyCompare());// 传进来一个比较器对象,使数组按比较器定义的规则来排序 12 for (Person i : people) { 13 System.out.println(i); 14 } 15 } 16 } 17 18 class Person { 19 String name; 20 int age; 21 public Person() {} 22 23 public Person(String name, int age) { 24 this.name = name; 25 this.age = age; 26 } 27 28 public String toString() { 29 return "姓名:" + name + ",年龄:" + age; 30 } 31 } 32 33 class MyCompare implements Comparator<Person> {// 定义比较器 34 /* 35 * 36 * 重写比较方法compare(o1,o2): 37 * 方法传进来两个对象,用两个对象的某属性进行对比,返回一个int。 38 * int>0,则o1排在o2后面; 39 * int<0,则o1排在o2前面; 40 * int=0,则维持原相对位置,即原来存放时o1、o2的前后地址顺序。 * 41 */ 42 public int compare(Person o1, Person o2) { 43 int result; 44 if (o1.age > o2.age) { 45 result = 1; 46 } else if (o1.age < o2.age) { 47 result = -1; 48 } else { 49 result = 0; 50 } 51 return result; 52 } 53 }
第三种:用list的子类:Vector、ArrayList存放对象们,调用Collections.sort(list,comparator)方法进行排序。
1 public class CollectionsTest { 2 3 public static void main(String[] args) { 4 Vector<Person> people = new Vector<>();// 用向量保存对象 5 // ArrayList<Person> people=new ArrayList<>()://用ArrayList保存对象。 6 people.add(new Person("小明", 20)); 7 people.add(new Person("小张", 30)); 8 people.add(new Person("小刘", 18)); 9 people.add(new Person("小林", 17)); 10 people.add(new Person("小刘", 35)); 11 Collections.sort(people, new MyComparator());// 调用方法进行排序 12 Iterator it = people.iterator(); 13 while (it.hasNext()) { 14 System.out.println(it.next()); 15 } 16 } 17 } 18 19 class Person { 20 String name; 21 int age; 22 23 public Person() {} 24 25 public Person(String name, int age) { 26 this.name = name; 27 this.age = age; 28 } 29 30 public String toString() { 31 return "姓名:" + name + ",年龄:" + age; 32 } 33 34 } 35 36 class MyComparator implements Comparator<Person> {// 实现Comparator接口,自定义比较器,实现compare方法定义比较算法 37 /* 38 * compare(o1,o2):方法传进两个对象,根据某属性进行比较,返回一个int值。 int>0,o1排在o2后; int<0,o1排在o2前; 39 * int=0,维持原来存放时的相对位置。 40 * 41 */ 42 public int compare(Person p1, Person p2) { 43 int result = p1.age < p2.age ? 1 : (p1.age == p2.age ? 0 : -1);// 降序排列 44 // int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//升序排列 45 46 if (result == 0) { 47 result = p1.name.compareTo(p2.name); 48 } 49 return result; 50 } 51 }
通过匿名比较器进行排序
1 public static List<String> sortAsFloat(List<String> list, final boolean reverseOrder) { 2 Collections.sort(list, new Comparator<String>(){ 3 4 public int compare(String o1, String o2) { 5 if (reverseOrder) { 6 return (int) (Float.parseFloat(o2) - Float.parseFloat(o1)); 7 } else { 8 return (int) (Float.parseFloat(o1) - Float.parseFloat(o2)); 9 } 10 } 11 }); 12 13 return list; 14 }

浙公网安备 33010602011771号