java刷题必备排序,Arrays.sort()和Collections.sort()
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()排序的结果一样。