在收集对象以后,对对象进行排序是经常使用的动做。不用亲自操做排序算法Java.util. Collections提供有sort()方法。因为必须有索引才能进行排序,所以 Collections的sort()方法接受List操做对象。例如:java
package coll_map; import java.util.*; public class SortDemo { public static void main(String[] args) { List nums=Arrays.asList(3,6,2,7,5,9,0); Collections.sort(nums); System.out.println(nums); } }
1.操做 Comparable算法
package coll_map; import java.util.*; class Sort2 { private String name; private String ID; private int balance; Sort2(String name, String ID, int balance) { this.name = name; this.balance = balance; this.ID = ID; } @Override public String toString() { return String.format("帐户(%s,%s,%d)", name,ID,balance); } } public class Account{ public static void main(String[] args) { List accounts=Arrays.asList( new Sort2("zhangsan","9958X",999), new Sort2("lisi","8779g",577), new Sort2("wanger","99098X",6988) ); Collections.sort(accounts); System.out.println(accounts); } }
抛错: java.lang.ClassCastException 是由于Collections的sort方法,不知道是根据 Account的name、ID或 balance进行排序。sort()方法要求被排序的对象必须操做java.lang. Comparable接口,这个接口有个 compareto()方法必须返回大于0、等于0或小于0的数:数组
package coll_map; import java.util.*; class Sort2 implements Comparable<Sort2>{ private String name; private String ID; private int balance; Sort2(String name, String ID, int balance) { this.name = name; this.balance = balance; this.ID = ID; } @Override public String toString() { return String.format("帐户(%s,%s,%d)", name,ID,balance); } @Override public int compareTo(Sort2 o) { // TODO 自动生成的方法存根 return this.balance-o.balance;//判断排序条件 } } public class Account{ public static void main(String[] args) { List accounts=Arrays.asList( new Sort2("zhangsan","9958X",999), new Sort2("lisi","8779g",577), new Sort2("wanger","99098X",6988) ); Collections.sort(accounts); System.out.println(accounts); } }
collections的sot()方法在取得a对象与b对象进行比较时,会先将a对象扮演(Cast)为 comparable(也所以若对象没操做 Comparable,将会抛出 Classcastexception),而后调用 a.compareto(b),若是a对象顺序上小于b对象则返回小于0的值,若顺序上相等则返回0,若顺序上a大于b则返回大于0的值。所以,上面的范例,将会依余额从小到大排列帐户对象。前面的Sort类中,能够直接对 Integer进行排序,由于Integer就有操做 Comparable接口。 2.操做Comparator String有操做Comparable:ide
package coll_map; import java.util.*; public class SortDemo { public static void main(String[] args) { List words=Arrays.asList("D","A","H","Y","E"); Collections.sort(words); //若是只想用String的compareTo方法能够:words.sort(String::compareTo); System.out.println(words); } }
可是若是有对象没法操做Comparable、拿不到原始码或者不能修改原始码。 好比让String排序结果反过来,就算修改String. Java后从新编译为 String.clas放回 rt jar中,也只有这个的JRE能够用,这已经不是标准API了。继承 string后再从新定义 compareto()也不可能,由于 String声明为 final,不能被继承。 Collections的sort()方法有另外一个重载版本,可接受 Java util. **Comparator接口的操做对象,若是使用这个版本,排序方式将根据 Comparator的 compare()定义来决定。**例如:this
package coll_map; import java.util.*; public class SortDemo { public static void main(String[] args) { List<String> words=Arrays.asList("D","A","H","Y","E"); Collections.sort(words,new StringSort()); System.out.println(words); } } class StringSort implements Comparator<String>{ @Override public int compare(String o1, String o2) { // TODO 自动生成的方法存根 return -o1.compareTo(o2); } }
Comparator的 compare()会传入两个对象,若是o1顺序上小于o2则返回小于0的值,顺序相等则返回0,顺序上o1大于o2则返回大于0的值。在这个范例中,因为 string自己就是 Comparable,因此将 compareto()返回的值乘上-1,就能够调换排列顺序。3d
package coll_map; import java.util.*; public class SortDemo { public static void main(String[] args) { List<String> words=Arrays.asList("D","A","H","Y","E"); //Collections.sort(words,(o1,o2) ->-o1.compareTo(o2));利用Lambda语法 words.sort((o1,o2) ->-o1.compareTo(o2));//更简单利用Lambda语法 System.out.println(words); } }
在Java的规范中,与顺序有关的行为,一般要不对象自己是 Comparable,要不就是另行指定 Comparator对象告知如何排序。 例如,若是想针对数组进行排序,可使用java.util.Arrays的sort()方法,若是查询API文件,会发现该方法针对对象排序时有两个版本:一个版本是你收集在数组中的对象必须是 Comparable()不然会抛出Classcastexception ,另外一个版本则能够传入 compa rato指定排序方式.
Set的操做类之一java. util. TreeSet不只拥有收集不重复对象的能力,还可用红黑树方式排序收集的对象,条件就是收集的对象必须是 comparable(不然会抛出 Classcastexception)或者是在建立TreeSet时指定 Comparator 对象。 Queue的操做类之一 java util. Priorityqueue也是,收集至 Priorityqueue的对象,会根据你指定的优先权来决定对象在队列中的序,优先权的告知,要不就是对象必须是 comparable(不然会抛出Classcastexception)或者是建立Priorityqueue时指定Comparator对象。 若是有个List中某些索引处包括null,如今让null排在最前头,以后依字符串的长度由大到小排序,这样从新定义compare:code
@Override public int compare(String o1, String o2) { if(o1==o2) { return 0; } if(o1==null) { return -1; } if(o2==null) { return 1; } if(o1.length()==o2.length()) { return 0; } if(o1.length()>o2.length()) { return -1; } return 1; }
固然其实能够利用高级语义API:orm
package coll_map; import java.util.*; import static java.util.Comparator.*; public class SortDemo { public static void main(String[] args) { List<String> words=Arrays.asList("D","A","H","Y","E"); words.sort(nullsFirst(reverseOrder));//高级语义 System.out.println(words); } }
reverseOrder()返回的 Comparator会是 Comparable对象上定义顺序的反序, nullsFirst接受 Comparator,在其定义的顺序上加上让null排在最前面的规则。 能够看到 import static适当的运用,可让程序码表达出自己操做的意图相比如下程序代码来讲清楚许多:对象
words.sort(Comparator.nullsFirst(Comparator.reverseOrder));
Conparator上还有不少方法可使用,例如 comparing与 thenComparing等方法,要运用这些方法,得了解更多JDK8的 Lambda特性,例如位于java.util.function套件中的 Function等接口的意义blog