排序总结(数组排序,ArrayList排序,HashMap排序)
一.数组排序
两种方式:
(1)直接调用sort方法
String[] s = new String[10];
Arrays.sort(s);
(2)自定义sort方法
String[] s = new String[10];
Arrays.sort(s,Arrays.sort(s, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}););
注意:
- Arrays.sort()方法既能对int数组进行排序,也能对String进行排序,但是默认是从小到大排序,若要进行倒序排序,只能用自定义sort方法排序。
- 用自定义方法对字符串数组进行排序时,compare()方法的返回值是int类型,若返回o1-o2,则会报错。
- 正确做法是使用String类中的compareTo方法进行字符串比较并返回一个int值,源码如下:
二.ArrayList排序
ArrayList底层为Object数组,排序方式和数组类似。
两种方法
(1)直接调用sort方法
List<Integer> integers = new ArrayList<>();
Collections.sort(integers);
(2)自定义sort方法
List<Integer> integers = new ArrayList<>();
Collections.sort(integers,new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}););
三.TreeSet排序
两种方法
(1)定义可排序对象,直接添加进TreeSet中
TreeSet可是采用两种方法实现排序:自然排序和定制排序。默认情况,TreeSet采用自然排序。
如果想采用自然排序,则要存储的对象所属类必须实现Comparable 接口。该接口只有一个方法public int compareTo(Object obj),必须实现该方法。
定义一个学生类,输入五个学生信息,按照学生成绩从高到底排序并输出(姓名-语文-数学-英语)
public class Student implements Comparable<Student> {
public String name;
public int chinese;
public int english;
public int math;
public int total;
public Student() {
}
public Student(String name, int chinese, int english, int math, int total) {
this.name = name;
this.chinese = chinese;
this.english = english;
this.math = math;
this.total = total;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", chinese=" + chinese +
", english=" + english +
", math=" + math +
", total=" + total +
'}';
}
@Override
public int compareTo(Student o) {
return o.total-this.total;
}
}
class StudentTest{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Set<Student> set = new TreeSet<Student>();
for(int i=0;i<5;i++){
System.out.println("姓名-语文-英语-数学");
String name=scanner.nextLine();
String[] strings = name.split("-"); //以-分隔字符串
int chinese=Integer.valueOf(strings[1]); //添加进treeset
int english=Integer.valueOf(strings[2]);
int math=Integer.valueOf(strings[3]);
Student student = new Student(strings[0], chinese, english, math, chinese + english + math);
set.add(student);
}
System.out.println(set);
}
}
运行结果
(2)定制排序
我们可以自定义(Comparator)比较器,在创建TreeSet集合对象时把我们自定义的比较器传入,则可以TreeSet会按照我们的比较器中定义的规则进行排序。
class StudentTest{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Set<Student> set = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.total-o1.total;
}
});
for(int i=0;i<5;i++){
System.out.println("姓名-语文-英语-数学");
String name=scanner.nextLine();
String[] strings = name.split("-");
int chinese=Integer.valueOf(strings[1]); //添加进treeset
int english=Integer.valueOf(strings[2]);
int math=Integer.valueOf(strings[3]);
Student student = new Student(strings[0], chinese, english, math, chinese + english + math);
set.add(student);
}
System.out.println(set);
}
}
运行结果也是相同的
注意:
- 定义排序对象是自定义类来实现comparable接口,定制排序则是实现comparator接口,不要混淆。
- 实现两个接口需要重写的方法也不同,前者重写compareTo方法,后者重写compare方法。
小Demo
需求:将一个数组元素去重后排序
java int[] arr={4,2,324,6,435,12,49,21,6,21,15,88};
方法一:
将数组元素添加进TreeSet中,实现comparator接口进行自定义排序
int[] arr={4,2,324,4,435,12,6,49,6,21,15,21,88};
TreeSet<Integer> set = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
for(int i=0;i<arr.length;i++){
set.add(arr[i]);
}
for (Integer i :
set) {
System.out.print(i+"\t");
}
结果:
方法二:
使用Integer,Double等常用类作为treeset的引用类型,它们已经重写过compare方法,直接添加进treeset即可。
int[] arr={4,2,324,4,435,12,6,49,6,21,15,21,88};
TreeSet<Integer> set = new TreeSet<>();
for (Integer i :
set) {
System.out.print(i+"\t");
}
- 注意:使用TreeSet存储数据时,引用类型必须实现comparator接口并且重写compare方法,因为在添加元素时Treeset会调用元素的compare方法。因此若元素的引用类型为自定义的类,又没有重写compare方法,程序就会报错。但是使用Integer,Double等常用类作为引用类型,它们已经重写过compare方法,可以直接使用。
HashMap排序
- 待更新
总结:
在对集合进行排序之前,一定要清楚集合底层的数据结构是怎样的,进行排序时,集合又做了什么,避免不必要的错误。