sort方法的使用很是的簡單明瞭,下面的例子中,先定義一個比較Dog大小的Comparator,而後將其實例對象做爲參數傳給sort方法,經過此示例,你應該可以快速掌握Arrays.sort()的使用方法。java
import java.util.Arrays; import java.util.Comparator; class Dog{ int size; public Dog(int s){ size = s; } } class DogSizeComparator implements Comparator<Dog>{ @Override public int compare(Dog o1, Dog o2) { return o1.size - o2.size; } } public class ArraySort { public static void main(String[] args) { Dog d1 = new Dog(2); Dog d2 = new Dog(1); Dog d3 = new Dog(3); Dog[] dogArray = {d1, d2, d3}; printDogs(dogArray); //或者採用匿名內部類 /** Arrays.sort(dogArray, new Comparator<Dog>(){ @Override public int compare(Dog o1, Dog o2) { return o1.size - o2.size; } }); */ Arrays.sort(dogArray, new DogSizeComparator()); printDogs(dogArray); } public static void printDogs(Dog[] dogs) for(Dog d: dogs) System.out.print(d.size + " " ); System.out.println(); } }
這是策略模式(Strategy pattern)的一個完美又簡潔的示例,值得一提的是爲何這種場景下適合使用策略模式。
整體來講,策略模式容許在程序執行時選擇不一樣的算法。好比在排序時,傳入不一樣的比較器(Comparator),就採用不一樣的算法。
根據上面的例子,假設你想要根據Dog的重量來進行排序,能夠像下面這樣,建立一個新的比較器來進行排序:算法
class Dog{ int size; int weight; public Dog(int s,int w){ size = s; weight = w; } } class DogSizeComparator implements Comparator<Dog>{ @Override public int compare(Dogo1,Dogo2){ return o1.size - o2.size; } } class DogWeightComparator implements Comparator<Dog>{ @Override public int compare(Dogo1,Dogo2){ return o1.weight - o2.weight; } } public class ArraySort{ public static void main(String[] args){ Dog d1 = new Dog(2,50); Dog d2 = new Dog(1,30); Dog d3 = new Dog(3,40); Dog[] dogArray = {d1,d2,d3}; printDogs(dogArray); Arrays.sort(dogArray, new DogSizeComparator()); printDogs(dogArray); Arrays.sort(dogArray,new DogWeightComparator()); printDogs(dogArray); } public static void printDogs(Dog[]dogs){ for(Dog d : dogs) System.out.print("size=" + d.size + "weight=" + d.weight + ""); System.out.println(); } }
Comparator是一個接口,因此sort方法中能夠傳入任意實現了此接口的類的實例,這就是策略模式的主要思想。ide
若是使用「Comparator < T > c」那是很簡單易懂的,可是sort的第2個參數裏面的< ? super T >意味着比較器所接受的類型能夠是T或者它的超類,爲何是超類呢? 答案是:這容許使用同一個比較器對不一樣的子類對象進行比較。在下面的示例中很明顯地演示了這一點:this
import java.util.Arrays; import java.util.Comparator; class Animal{ int size; } class Dog extends Animal{ public Dog(int s){ size = s; } } class Cat extends Animal{ public Cat(int s){ size= s; } } class AnimalSizeComparator implements Comparator<Animal>{ @Override public int compare(Animal o1, Animal o2) { return o1.size - o2.size; } //in this way, all sub classes of Animal can use this comparator. } public class ArraySort { public static void main(String[] args) { Dog d1 = new Dog(2); Dog d2 = new Dog(1); Dog d3 = new Dog(3); Dog[] dogArray = {d1, d2, d3}; printDogs(dogArray); Arrays.sort(dogArray, new AnimalSizeComparator()); printDogs(dogArray); System.out.println(); //when you have an array of Cat, same Comparator can be used. Cat c1 = new Cat(2); Cat c2 = new Cat(1); Cat c3 = new Cat(3); Cat[] catArray = {c1, c2, c3}; printDogs(catArray); Arrays.sort(catArray, new AnimalSizeComparator()); printDogs(catArray); } public static void printDogs(Animal[] animals){ for(Animal a: animals) System.out.print("size="+a.size + " "); System.out.println(); } }
public class Student implements Comparable<Student> { String name; int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return name + ":" + age; } @Override public int compareTo(Student o) { return Comparators.NAME.compare(this, o); } public static class Comparators { public static Comparator<Student> NAME = new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return o1.name.compareTo(o2.name); } }; public static Comparator<Student> AGE = new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return o1.age - o2.age; } }; public static Comparator<Student> NAMEANDAGE = new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int i = o1.name.compareTo(o2.name); if (i == 0) { i = o1.age - o2.age; } return i; } }; } } //用法 List<Student> studentList = new LinkedList<>(); Collections.sort(studentList, Student.Comparators.AGE);
package leetcode; /** * Created by slyuan on 17-4-18. */ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class SortMapByValue { public static boolean ASC = true; public static boolean DESC = false; public static void main(String[] args) { // Creating dummy unsorted map Map<String, Integer> unsortMap = new HashMap<String, Integer>(); unsortMap.put("B", 55); unsortMap.put("A", 80); unsortMap.put("D", 20); unsortMap.put("C", 70); System.out.println("Before sorting......"); printMap(unsortMap); System.out.println("After sorting ascending order......"); Map<String, Integer> sortedMapAsc = sortByComparator(unsortMap, ASC); printMap(sortedMapAsc); System.out.println("After sorting descindeng order......"); Map<String, Integer> sortedMapDesc = sortByComparator(unsortMap, DESC); printMap(sortedMapDesc); } private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap, final boolean order) { List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(unsortMap.entrySet()); // Sorting the list based on values Collections.sort(list, new Comparator<Entry<String, Integer>>() { public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { if (order) { return o1.getValue().compareTo(o2.getValue()); } else { return o2.getValue().compareTo(o1.getValue()); } } }); // Maintaining insertion order with the help of LinkedList Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>(); for (Entry<String, Integer> entry : list) { sortedMap.put(entry.getKey(), entry.getValue()); } return sortedMap; } public static void printMap(Map<String, Integer> map) { for (Entry<String, Integer> entry : map.entrySet()) { System.out.println("Key : " + entry.getKey() + " Value : "+ entry.getValue()); } } }
//另外一種實現方式 public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue( Map<K, V> map ) { List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>( map.entrySet() ); Collections.sort( list, new Comparator<Map.Entry<K, V>>() { public int compare( Map.Entry<K, V> o1, Map.Entry<K, V> o2 ) { return (o1.getValue()).compareTo( o2.getValue() ); } } ); Map<K, V> result = new LinkedHashMap<K, V>(); for (Map.Entry<K, V> entry : list) { result.put( entry.getKey(), entry.getValue() ); } return result; }
Using the TreeMap you can sort the Map, 默認狀況下,TreeMap對key進行升序排序code
Map<String, String> unsortMap = new HashMap<String, String>(); Map<String, String> treeMap = new TreeMap<String, String>(unsortMap); for (String str : treeMap.keySet()) { System.out.println(str); }
注意:正常狀況下Map是不可使用Collections.sort()方法進行排序的,不過能夠將Map轉換成list以後再進行排序。對象
List<Entry<String,Integer>> list = new LinkedList<>(unsortMap.entrySet()); Collections.sort(list, new Comparator<Entry<String, Integer>>() { @Override public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) { return e1.getKey().compareTo(e2.getKey()); } });