Arrays.sort()和Collections.sort()

Arrays.sort()对数组进行排序,Collections.sort()对list集合进行排序。

被排序的元素分为两类:一是,基本数据类型(或对应包装类);二是,自定义的实体类。

基本数据类型(或包装类型)

对于基本数据类型,使用Array.sort() ,默认是升序。第二个参数传入:Collections.reverseOrder()即可实现降序,想要实现降序,数组中元素的类型得是基本类型的包装类。

对于基本数据类型的包装类,使用Collections.sort(),默认是升序。第二个参数传入:Collections.reverseOrder()即可实现降序,或者先升序,然后通过Collections.reverse(list)可以实现反序,也算是降序了。

自定义实体类

对于元素类型为自定义实体类,Array.sort()和Collections.sort()都需要自定义排序,只不过一个对数组进行排序,一个对list集合进行排序,但是数组及list集合中元素必须实现Comparable接口(或者使用Comparator接口),这里暂时只记录了使用Comparable接口的情况。

(说白了,想要排序,总要告诉计算机应该按照什么样的规则来排序吧,基本数据类型或者包装类可以按照数值大小来排序,自定义的实体类,鬼知道你想要按什么样的规则进行排序,所以需要告诉计算机你的排序规则是什么,用什么来告诉计算机呢,java提供了两个用于排序的接口Comparable和Comparator,通过使用这两个接口,使用一个就好,按照想法自定义排序规则,让计算机照办即可。基本数据类型的包装类本身就已经实现该接口,不需要coder操心,但是自己定义的实体类元素的排序,就需要自己写排序规则了。)

自然排序--Comparable接口

定制排序--Comparator接口

自然排序:

Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。

obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等;如果返回一个正数,则表明obj1大于obj2;如果是负数,则表明obj1小于obj2。一般来说,返回值为:-1,0,1。

不论是基本数据类型(或包装类),还是自定义类型,返回值大于0,表示两个元素需要更换位置,否则就是不需要更换位置。例如,为1表示需要更换两个元素的位置,-1表示不需要更换。(obj1可以认为是当前位置元素,obj2可以认为是下个位置的元素)

定制排序:

Java提供了一个Comparator接口,该接口定义了一个compare(To1,To2)方法。单独定义一个实现了该接口的类,然后重写compare(To1,To2)方法,实例对象作为第二个参数即可。还可以写成匿名内部类。

1、基于Arrays.sort()实现数组升序和降序

(1)元素为基本数据类型

//Arrays.sort()对元素为整型的数组进行排序
int[] a = new int[]{1,4,2,3,5};
System.out.println("排序前:");
System.out.println(Arrays.toString(a));
//Arrays.sort(a);//默认升序
Arrays.sort(a,0,5);//效果同上,对下标0到下标为(5-1)等5个元素进行排序,参数可变。
System.out.println("升序后:");
System.out.println(Arrays.toString(a));
		
//Arrays.sort()降序,元素不能是基本数据类型,需要改成对应的包装类
//基本类型的包装类实现了Comparable接口
Integer[] aa = new Integer[5];
for(int i=0;i<5;i++){
	aa[i] = new Integer(a[i]);
}
Arrays.sort(aa,Collections.reverseOrder());
System.out.println("降序后:");
System.out.println(Arrays.toString(aa));



执行结果:

排序前:
[1, 4, 2, 3, 5]
升序后:
[1, 2, 3, 4, 5]
降序后:
[5, 4, 3, 2, 1]

(2)元素为实体类(自定义排序)

这里定义了个实体类为Person,内部设定三个属性为语、数、英三门课的分数。自定义排序:尽可能让语文分数高的往前排,如果语文成绩相同,尽可能让数学成绩好的往前排,如果数学成绩相同,尽可能让英语成绩好的往前排。compareTo()方法返回值大于0,交换两个元素。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
 
public class sortTest {
 
	public static void main(String[] args) {
						
		//Arrays.sort()对元素为实体类的数组进行排序
		Person[] arr = new Person[100];
		arr[0] = new Person(89,99,92);
		arr[1] = new Person(89,89,92);
		arr[2] = new Person(90,99,90);
		arr[3] = new Person(89,99,100);
		arr[4] = new Person(90,99,98);
		
		System.out.println("排序前:");
		
		for(int i=0;i<5;i++){
			System.out.println(arr[i].chineseScore+" "+arr[i].mathScore+" "+arr[i].eglishScore);
		}
					
		Arrays.sort(arr);
		
		System.out.println("排序后:");
		for(int i=0;i<5;i++){
			System.out.println(arr[i].chineseScore+" "+arr[i].mathScore+" "+arr[i].eglishScore);
		}
		
	}
 
}
 
class Person implements Comparable<Person>{
	
	int chineseScore;
	int mathScore;
	int eglishScore;
	
	public Person(int chineseScore,int mathScore,int eglishScore){
		this.chineseScore = chineseScore;
		this.mathScore = mathScore;
		this.eglishScore = eglishScore;
	}
	
	@Override
	public int compareTo(Person o) {
		if(this.chineseScore != o.chineseScore){ 
			if(this.chineseScore < o.chineseScore) return 1;
		}else if(this.mathScore != o.mathScore){
			if(this.mathScore < o.mathScore) return 1;
		}else if(this.eglishScore != o.eglishScore){
			if(this.eglishScore < o.eglishScore) return 1;
		}			
		return -1;
	}
	
}

执行结果:

排序前:
89 99 92
89 89 92
90 99 90
89 99 100
90 99 98
排序后:
90 99 98
90 99 90
89 99 100
89 99 92
89 89 92

2、Collections.sort()实现list集合升序和降序

(1)元素为基本数据类型的包装类

List<Integer> list = new ArrayList<Integer>();
list.add(1);//1 自动转为包装类Integer
list.add(5);
list.add(2);
list.add(3);
 
System.out.println("排序前:");
System.out.println(Arrays.toString(list.toArray()));
 
Collections.sort(list);		
System.out.println("升序后:");
System.out.println(Arrays.toString(list.toArray()));
		
System.out.println("降序后:");
//Collections.reverse(list);//对升序后的内容反序,也算是降序了吧
Collections.sort(list,Collections.reverseOrder());
System.out.println(Arrays.toString(list.toArray()));

 执行结果:

排序前:
[1, 5, 2, 3]
升序后:
[1, 2, 3, 5]
降序后:
[5, 3, 2, 1]

(2)元素为实体类(自定义排序)

这里定义了个实体类为Person,内部设定三个属性为语、数、英三门课的分数。自定义排序:尽可能让语文分数高的往前排,如果语文成绩相同,尽可能让数学成绩好的往前排,如果数学成绩相同,尽可能让英语成绩好的往前排。compareTo()方法返回值大于0,交换两个元素。

package com.wmm;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
 
public class sortTest {
 
	public static void main(String[] args) {		
		//Collections.sort()对列表就进行排序
		List<Person> list = new ArrayList<Person>();
		list.add(new Person(89,99,92));
		list.add(new Person(89,89,92));
		list.add(new Person(90,99,90));
		list.add(new Person(89,99,100));
		list.add(new Person(90,99,98));
		
		System.out.println("排序前:");
		for(Person p:list){
			System.out.println(p.chineseScore+" "+p.mathScore+" "+p.eglishScore);
		}
		
		Collections.sort(list);
		
		System.out.println("排序后:");		
		for(Person p:list){
			System.out.println(p.chineseScore+" "+p.mathScore+" "+p.eglishScore);
		}
	}
 
}
 
class Person implements Comparable<Person>{
	
	int chineseScore;
	int mathScore;
	int eglishScore;
	
	public Person(int chineseScore,int mathScore,int eglishScore){
		this.chineseScore = chineseScore;
		this.mathScore = mathScore;
		this.eglishScore = eglishScore;
	}
	
	@Override
	public int compareTo(Person o) {
		if(this.chineseScore != o.chineseScore){ 
			if(this.chineseScore < o.chineseScore) return 1;
		}else if(this.mathScore != o.mathScore){
			if(this.mathScore < o.mathScore) return 1;
		}else if(this.eglishScore != o.eglishScore){
			if(this.eglishScore < o.eglishScore) return 1;
		}			
		return -1;
	}
	
}

执行结果:

排序前:
89 99 92
89 89 92
90 99 90
89 99 100
90 99 98
排序后:
90 99 98
90 99 90
89 99 100
89 99 92
89 89 92

3、有序集合(TreeMap、TreeSet)

TreeMap集合默认会对键进行排序,所以键必须实现自然排序和定制排序中的一种。

TreeSet集合默认对元素进行排序,所以元素必须实现自然排序和定制排序中的一种。

(集合中元素都是引用类型,包括基本数据类型的包装类也是引用类型,基本数据类型的包装类已经实现了排序程序,然而我们自己写的实体类,自定义排序的程序需要自己写,就如上述程序)

(1)TreeMap

(1)TreeMapMap<Integer,String> map = new TreeMap<Integer,String>();		
map.put(3, "nanjing");
map.put(1, "beijing");
map.put(2, "dongjing");		
for(Integer key:map.keySet()){
	System.out.println(key);
}

执行结果:

1
2
3

(2)TreeSet

Set<Person> set = new TreeSet<Person>();
set.add(new Person(89,99,92));
set.add(new Person(89,89,92));
set.add(new Person(90,99,90));
set.add(new Person(89,99,100));
set.add(new Person(90,99,98));
		
for(Person p:set){
	System.out.println(p.chineseScore+" "+p.mathScore+" "+p.eglishScore);
}

执行结果:

90 99 98
90 99 90
89 99 100
89 99 92
89 89 92

//Person类中,自定义的排序方式一样,故TreeSet自动排序结果,与上述使用Arrays.sort()、Conllections.sort()排序的结果一样。