# 集合排序
[TOC]
## 集合中基本数据类型排序
**使用 Collections.sort(list) 进行排序**
1. 集合中的元素类要实现 Comparable 接口,重写 compareTo 方法;
2. 调用 Collections.sort(list) 完成排序
根据元素的*自然顺序*对指定列表按升序进行排序。
~~~
public class IntSort {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(3);
list.add(5);
list.add(8);
list.add(1);
list.add(4);
System.out.print("排序前的数据: ");
for(Integer it : list) {
System.out.print(it + " ");
}
Collections.sort(list);
System.out.print("排序后的数据: ");
for(Integer it : list) {
System.out.print(it + " ");
}
System.out.print("反转后的数据: ");
Collections.reverse(list);
for(Integer it : list) {
System.out.print(it + " ");
}
}
}
~~~
## 集合中字符串排序
>[info] 字符串是按照其首字母对应的ASCII(Unicode)码值进行排序的。
~~~
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class StringSort {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("orange");
list.add("red");
list.add("blue");
list.add("yellow");
System.out.print("排序前顺序: ");
for(String color : list) {
System.out.print(color + " ");
}
Collections.sort(list);
System.out.println();
System.out.print("排序后顺序: ");
for(String color : list) {
System.out.print(color + " ");
}
}
}
~~~
**对于自定义的类我们将使用Comparator和Comparable接口进行排序**
## Comparator接口
* 是可以强行对某个对象进行整体排序的比较器
* 可以将Comparator接口作为参数传递给sort方法(如 Collections.sort 或 Arrays.sort)
* Comparator接口存在int compare(T o1, T o2)方法, 用来比较排序的两个参数:
a. 如果 o1 < o2,返回负整数;
b. 如果 o1 == o2,返回0;
c. 如果 o1 > o2,返回正整数。
* boolean equals(Object obj) 指示某个其他对象是否“等于”此Comparator;此方法可以被Object类中的equals方法覆盖,不必重写。
**根据自定义的数据类型中的String类型,进行排序**
~~~
public class Student {
private String name;
private String code;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, String code, int age) {
super();
this.name = name;
this.code = code;
this.age = age;
}
public Student() {
super();
}
@Override
public String toString() {
return "Student [名字=" + name + ", 学号=" + code + ", 年龄=" + age + "]";
}
}
/**
* 重写compare方法,在此方法中描写我们的排序依据
* @author LiXinRong
*
*/
public class NameComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
String name1 = o1.getName();
String name2 = o2.getName();
//compareTo()方法
//如果参数字符串等于此字符串,则返回值 0;
//如果此字符串按字典顺序小于字符串参数,则返回一个小于 0 的值;
//如果此字符串按字典顺序大于字符串参数,则返回一个大于 0 的值。
//按名字升序排序
int reult = name1.compareTo(name2);
//按名字降序排序
//int reult = name2.compareTo(name1);
return reult;
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ClassSort {
public static void main(String[] args) {
//按学生的名字升序进行排序
Student qdd = new Student("仇冬冬","001",25);
Student drm = new Student("丁润萌","002",21);
Student wc = new Student("王晨","003",25);
Student lzj = new Student("刘子杰","004",22);
Student qh = new Student("邱晗","005",22);
List<Student> list = new ArrayList<Student>();
list.add(qdd);
list.add(drm);
list.add(wc);
list.add(lzj);
list.add(qh);
System.out.println("排序前顺序:");
for(Student stu : list) {
System.out.println(stu);
}
//进行排序
Collections.sort(list, new NameComparator());
System.out.println("排序后顺序:");
for(Student stu : list) {
System.out.println(stu);
}
}
}
~~~
**按年龄的降序排序**
~~~
import java.util.Comparator;
public class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
//按年龄进行降序排序
int age1 = o1.getAge();
int age2 = o2.getAge();
int result = age2 - age1;
return result;
}
}
public class ClassSort {
public static void main(String[] args) {
Student qdd = new Student("仇冬冬","001",25);
Student drm = new Student("丁润萌","002",21);
Student wc = new Student("王晨","003",25);
Student lzj = new Student("刘子杰","004",22);
Student qh = new Student("邱晗","005",22);
List<Student> list = new ArrayList<Student>();
list.add(qdd);
list.add(drm);
list.add(wc);
list.add(lzj);
list.add(qh);
System.out.println("排序前顺序:");
for(Student stu : list) {
System.out.println(stu);
}
////按学生的年龄降序进行排序
Collections.sort(list, new AgeComparator());
System.out.println("排序后顺序:");
for(Student stu : list) {
System.out.println(stu);
}
}
}
~~~
## Comparable接口
* 此接口强行对实现它的每个类的对象进行整体排序;
* 这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法;
* 对于集合,通过调用Collections.sort方法进行排序;
* 对于数组,通过调用Arrays.sort方法进行排序;
* int compareTo(T o) 方法,该对象(实现Comparable接口的对象)小于、等于或大于指定对象(compareTo方法中的参数对象),则分别返回负整数、零或正整数。
~~~
public class Student implements Comparable<Student> {
private String name;
private String code;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, String code, int age) {
super();
this.name = name;
this.code = code;
this.age = age;
}
public Student() {
super();
}
@Override
public String toString() {
return "Student [名字=" + name + ", 学号=" + code + ", 年龄=" + age + "]";
}
@Override
public int compareTo(Student stu) {
int age = this.age;
int stuAge = stu.age;
int result = age - stuAge;
return result;
}
}
public class ClassSort {
public static void main(String[] args) {
Student qdd = new Student("仇冬冬","001",25);
Student drm = new Student("丁润萌","002",21);
Student wc = new Student("王晨","003",25);
Student lzj = new Student("刘子杰","004",22);
Student qh = new Student("邱晗","005",22);
List<Student> list = new ArrayList<Student>();
list.add(qdd);
list.add(drm);
list.add(wc);
list.add(lzj);
list.add(qh);
System.out.println("排序前顺序:");
for(Student stu : list) {
System.out.println(stu);
}
////按学生的年龄升序进行排序
Collections.sort(list);
System.out.println("排序后顺序:");
for(Student stu : list) {
System.out.println(stu);
}
}
}
~~~
## 练习
1. **在一个列表中存储以下元素:red、blue、orange、yellow。**
* **要求打印集合中最大和最小的元素**
~~~java
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("red");
list.add("blue");
list.add("orange");
list.add("yellow");
Collections.sort(list);
System.out.println("集合中最小的元素为:" + list.get(0));
System.out.println("集合中最大的元素为:" + list.get(list.size() - 1));
}
}
~~~
* **要求找出集合中长度最大和长度最小的元素**
~~~java
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("red");
list.add("blue");
list.add("orange");
list.add("yellow");
Collections.sort(list, new SortRule());
System.out.println("集合中长度最小的元素为:" + list.get(0));
System.out.println("集合中长度最大的元素为:" + list.get(list.size() - 1));
}
}
~~~
~~~java
public class SortRule implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
int result = o1.length() - o2.length();
return result;
}
}
~~~
2. **如何去除list(存储元素如下)集合中重复的元素并排序**
~~~
List<String> list = new ArrayList<String>();
list.add("1");
list.add("1");
list.add("22");
list.add("2");
list.add("3");
list.add("31");
list.add("3 1");
list.add("");
list.add("0");
list.add("\t");
~~~
~~~java
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("1");
list.add("1");
list.add("22");
list.add("2");
list.add("3");
list.add("31");
list.add("3 1");
list.add("");
list.add("0");
list.add("\t");
Demo.getDistinctList(list);
System.out.println(list);
}
/**
* 对list集合进行去重排序
* @param list
*/
public static void getDistinctList(List<String> list) {
//首先实现一个set接口
Set<String> set = new HashSet<String>();
//将list集合中的内容通过addAll方法全部添加到set集合中,并利用set集合不可存储重复元素的特性去重
set.addAll(list);
//清空原本的list集合
list.clear();
//可以将去重后的set集合的元素,再次添加到list集合中去
list.addAll(set);
//调用Collections接口的sort排序方法
Collections.sort(list);
}
}
~~~
3. **写一个Student类, 包含属性code\[1-30), grade\[1-6\], score\[0-100\], 所有属性都是随机生成(Math.random()方法,返回一个范围\[0,1)的随机数)
要求保存这二十位同学的信息,学号(code)不得相同, 并找出分数最高的同学和分数最低的同学, 最后打印输出最高分和最低分同学信息.**
~~~java
public class Student implements Comparable<Student>{
private int code;
private int grade;
private int score;
public Student(int code, int grade, int score) {
super();
this.code = code;
this.grade = grade;
this.score = score;
}
public Student() {
super();
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "Student [学号=" + code + ", 年级=" + grade + ", 分数=" + score + "]";
}
@Override
public int compareTo(Student o) {
int result = this.score - o.getScore();
return result;
}
}
~~~
~~~java
public class Demo {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();
Set<Integer> set = new HashSet<Integer>();
//将学号添加进set集合中,并保证set集合的大小不超过20
while(set.size() < 20) {
//获得学号的随机数[1,30)
//范围大的数据强制给范围小的数据进行赋值,会出现精度的缺失
int code = (int)(Math.random() * 29 + 1);//[0,1)
set.add(code);
}
for(int code : set) {
int grade = (int)(Math.random() * 6 + 1);
int score = (int)(Math.random() * 100 + 1);
list.add(new Student(code, grade, score));//匿名对象
}
for(Student stu: list) {
System.out.println(stu);
}
Collections.sort(list);
System.out.println("分数最低同学:" + list.get(0));
System.out.println("分数最高同学:" + list.get(list.size() - 1));
}
}
~~~