Java中Arrays.sort()和Collections.sort()

1.简单示例

sort方法的使用非常的简单明了,下面的例子中,先定义一个比较Dog大小的Comparator,然后将其实例对象作为参数传给sort方法,通过此示例,你应该能够快速掌握Arrays.sort()的使用方法。

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();
	}
}  

2.使用策略模式

这是策略模式(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方法中可以传入任意实现了此接口的类的实例,这就是策略模式的主要思想。

3.为何使用"super"

如果使用“Comparator < T > c”那是很简单易懂的,但是sort的第2个参数里面的< ? super T >意味着比较器所接受的类型可以是T或者它的超类,为什么是超类呢? 答案是:这允许使用同一个比较器对不同的子类对象进行比较。在下面的示例中很明显地演示了这一点:

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();
	}
}

4.Collections sort(List< T >,Comparator<? super T>) 用法

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);

5.Sorting HashMap by values(HashMap值排序)

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;
    }

5.Sorting HashMap by key

Using the TreeMap you can sort the Map, 默认情况下,TreeMap对key进行升序排序

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());
	}
});

posted @ 2017-04-18 16:01  Farnear  阅读(579)  评论(0编辑  收藏  举报