集合排序原理:
对集合的排序可分为:基本数据类型排序和字符串排序
对List集合的排序可以要用到java.util包下的collections类中的sort()方法
根据元素的自然顺序对指定列表按升序进行排序
所谓自然顺序:如果是整型的数据例如:1,2,3,4则会按照1,2,3,4进行排序。如果是字符数据则会按照对应字符的ASII值进行排序。
【案例】
对集合中的基本类型数据(这里用整型数据举例)进行排序
package com.jinglan.sort;
//对存储在List集合中的整型数据进行排序
import java.util.*;
public class IntSort {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();//创建集合指定存储类型
// 向集合中存入数据
list.add(1);
list.add(9);
list.add(8);
list.add(11);
System.out.println("排序前:");
for (int n : list) {//foreach循环
System.out.print(n + " ");
}
System.out.println();
System.out.println("排序后:");
// 利用Collections类中的sort()方法进行排序
Collections.sort(list);
for (int n : list) {
System.out.print(n + " ");
}
}
}
【运行结果】
【案例】
对集合中的字符串类型数据进行排序
package com.jinglan.sort;
//对存放在List的字符串进行排序
import java.util.ArrayList;
import java.util.Collections;
public class StringSort {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();// 创建集合指定存储类型为String型
// 将字符串存储到集合中
list.add("red");
list.add("green");
list.add("yello");
list.add("blue");
System.out.println("排序前:");
for (String s : list) {
System.out.print(s + " ");
}
System.out.println();
Collections.sort(list);// Collections.sort()进行排序
System.out.println("排序后:");
for (String s : list) {
System.out.print(s + " ");
}
}
}
【运行结果】
对自定义的类或对象进行排序要用到两个接口Comparator或Comparable。通过这两个接口去自定义排序的规则
Comparator接口:
1、可以强行对某个对象进行整体排序的一个比较函数,有时候称它为比较器。位于java.util包下
2、可以将Comparator接口作为一个参数传递给sort()方法。
对于自定义的对象,如果在集合中进行排序那么使用的是Collections.sort()在数组中进行排序使用的是Arrays.sort()
Comparator接口中包含两个方法:
int compare(T o1,T o2)其中o1、o2就是要用来比较的两个对象。
该方法的返回值及其所代表的含义:
如果o1<o2,返回负整数。
如果o1>o2,返回正整数。
如果o1==02,返回0。
boolean equals(Object obj)方法,指定对象是否“等于”当前对象。Object类中有一个同样的方法,Object类是所有类的根类,comparator接口中的equals()方法可以被Object类中的equals()方法覆盖,所以在对Comparator接口进行实现的时候,可以重写equals()方法也可以不重写。因为Object类已经重写过了,但是compare()方法是一定要重写的。
接下来是一个案例 这个案例用来实现 对于自定义的类 Cat 我想要对它的对象们进行排序 排序的规则是我自己的定义的:按照名字进行排序 (实质上就是字符串排序)
1、首先我要有个Cat类、里面定义了一些最基本的属性
2、创建一个比较类去实现Comparator接口,在这个类中定义比较规则
3、创建一个测试类,里面创建几个Cat对象,把它们放进集合里,然后利用Colletions.sort(List1ist,Comparator<? super T>c)方法排序出来
【Cat类】
package com.jinglan.sort;
public class Cat {
private String name;//名字
private int age;//年龄
private String species;//品种
//构造方法
public Cat(String name, int age, String species) {
super();
this.name = name;
this.age = age;
this.species = species;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
@Override
public String toString() {
return " [名字=" + name + ", 年龄=" + age + ", 品种=" + species + "]";
}
}
【比较类】
package com.jinglan.sort;
import java.util.Comparator;
public class CatNameComparator implements Comparator<Cat> {//定义了一个CatNameComparator类实现Comparator接口对Cat进行比较
//重写compare()方法
public int compare(Cat o1,Cat o2) {//对o1、o2进行某种比较
//按名字升序排序 名字比较
String name1 = o1.getName();
String name2 = o2.getName();
int n = name1.compareTo(name2);//compareTo()对两个**字符串**!!!!进行比较,比较的结果就根据返回的int类型的变量值情况判断跟compare()的比较规则一样
return n;
//compare()方法的返回值是由compareTo()方法的返回值决定的,刚好两个方法的返回值意义是一样的,于是就实现了比较
}
}
【测试类】
package com.jinglan.sort;
//测试
import java.util.*;
public class CatNameComparatorTest {
public static void main(String[] args) {
//创建Cat对象
Cat huahua = new Cat("huahau",2,"英国短毛猫");
Cat fanfan = new Cat("fanfan",3,"中华田园猫");
Cat jianjian = new Cat("jianjian",3,"中华田园猫");
//将对象存到集合中
ArrayList<Cat> CatList = new ArrayList<Cat>();
CatList.add(huahua);
CatList.add(fanfan);
CatList.add(jianjian);
//排序
System.out.println("排序前:");
for(Cat cat:CatList) {
System.out.println(cat);
}
System.out.println();
System.out.println("排序后:");
Collections.sort(CatList, new CatNameComparator());//对CatList集合中的对象进行比较,比较的依据就是CatNameComparator类中定义的
for(Cat cat:CatList) {
System.out.println(cat);
}
}
}
【运行结果】
上面的结果就实现了 升序排序,如果要进行降序排序只需要将【比较类】中
int n = name1.compareTo(name2);//compareTo()对两个字符串进行比较,比较的结果就根据返回的int类型的变量值情况判断跟compare()的比较规则一样
这一句代码中name1和name2的位置进行调换。具体原因,文末会统一解释。现在先不要纠结。
即:
int n = name2.compareTo(name1);//compareTo()对两个字符串进行比较,比较的结果就根据返回的int类型的变量值情况判断跟compare()的比较规则一样
【降序排列的运行结果】
上面的例子是对根据“名字”对对象进行升降排序,接下来根据“年龄”对对象进行升降排序
着重要改变的地方是【比较类】,对于【测试类】只是将对象的年龄做了一个改变 也将类名做了相应的更改 为了好看
【Cat类】
package com.jinglan.sort;
public class Cat {
private String name;//名字
private int age;//年龄
private String species;//品种
//构造方法
public Cat(String name, int age, String species) {
super();
this.name = name;
this.age = age;
this.species = species;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
@Override
public String toString() {
return " [名字=" + name + ", 年龄=" + age + ", 品种=" + species + "]";
}
}
【比较类】
package com.jinglan.sort;
import java.util.Comparator;
public class CatAgeComparator implements Comparator<Cat> {// 定义了一个CatAgeComparator类实现Comparator接口对Cat进行比较
// 重写compare()方法
public int compare(Cat o1, Cat o2) {// 对o1、o2进行某种比较
// 按年龄升序排序 年龄比较
int age1 = o1.getAge();
int age2 = o2.getAge();
return age1 - age2;
//compare()方法根据age1-age2的返回值情况 进行比较
}
}
【测试类】
package com.jinglan.sort;
//测试
import java.util.*;
public class CatAgeComparatorTest {
public static void main(String[] args) {
// 创建Cat对象
Cat huahua = new Cat("huahau", 1, "英国短毛猫");
Cat fanfan = new Cat("fanfan", 3, "中华田园猫");
Cat jianjian = new Cat("jianjian", 2, "中华田园猫");
// 将对象存到集合中
ArrayList<Cat> CatList = new ArrayList<Cat>();
CatList.add(huahua);
CatList.add(fanfan);
CatList.add(jianjian);
// 排序
System.out.println("排序前:");
for (Cat cat : CatList) {
System.out.println(cat);
}
System.out.println();
System.out.println("排序后:");
Collections.sort(CatList, new CatAgeComparator());// 对CatList集合中的对象进行比较,比较的依据就是CatNameComparator类中定义的
for (Cat cat : CatList) {
System.out.println(cat);
}
}
}
【运行结果】
同样的 如果想要对年龄进行降序排列 只需要将【比较类】中age1和age2的位置互换一下即可:
return age1 - age2;
改为:
return age2 - age1;
即可
【运行结果】
对上面的知识进行一个简单总结:集合(collection)或者数组(array)中对于基本数据类型和字符串类型的排序, 只需要Collections.sort()方法或者Array.sort() 即可将元素进行一个升序排列 对于自定义的对象进行排序 则需要 去实现一个接口Comparator,并且重写其中的compare()方法在方法中自定义排序规则。
针对上面的知识扩展一个练习题
【例题】
分析:
1、要有一个Student类
2、一个实现类去实现Comparator接口定义根据名字排序的规则
3、一个测试类完成测试任务
【Student类】
package com.jinglan.sort;
public class Student {
private int id;//学号
private int age;//年龄
private String name;//姓名
public Student(int id, int age, String name) {
super();
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return " [学号=" + id + ", 年龄=" + age + ", 姓名=" + name + "]";
}
}
【比较类】
package com.jinglan.sort;
import java.util.Comparator;
public class StudentNameComparator implements Comparator<Student> {
public int compare(Student o1,Student o2){
String name1 = o1.getName();
String name2 = o2.getName();
int n = name1.compareTo(name2);
return n;
}
}
【测试类】
package com.jinglan.sort;
import java.util.*;
public class StudentNameComparatorTest {
public static void main(String[] args) {
Student peter = new Student(40, 20, "peter");
Student angle = new Student(28, 5, "angle");
Student tom = new Student(35, 18, "tom");
ArrayList<Student> StudentList = new ArrayList<Student>();
StudentList.add(peter);
StudentList.add(angle);
StudentList.add(tom);
System.out.println("排序前:");
for(Student stu:StudentList){
System.out.println(stu);
}
System.out.println("排序后:");
Collections.sort(StudentList,new StudentNameComparator());
for(Student stu :StudentList){
System.out.println(stu);
}
}
}
【运行结果】
接下来是与Comparator同样功能的Comparable接口
Comparable接口
1、可以强行对每个实现它的对象进行整体排序。位于java.lang包下
2、这种排序被称为类的自然排序,compareTo()方法被称为它的自然比较方法。
2、可以将Comparable接口作为一个参数传递给sort()方法。
对于自定义的对象,如果在集合中进行排序那么使用的是Collections.sort()在数组中进行排序使用的是Arrays.sort()
Comparable接口中只包含一个方法:
该方法的比较规则:
观察返回值
该对象>指定对象,返回正整数。
该对象<指定对象,返回负整数。
该对象=指定对象,返回0
接下来是一个案例 这个案例用来实现 对于自定义的类Goods 我想要对它的对象们进行排序 排序的规则是我自己的定义的:按照价格进行排序 (实质上就是int类型排序)
分析:
1、首先我需要一个Goods类
2、让Goods类去实现Comparable接口并定义"根据价格"进行排序的规则
3、定义测试类实现测试功能
【案例】
【Goods】类
package com.jinglan.sort;
import java.lang.Comparable;
public class Goods implements Comparable<Goods> {// 定义Goods类并实现Comparable接口
private String id;// 商品编号
private String name;// 商品名称
private double price;// 商品价格
// 构造方法
public Goods(String id, String name, double price) {
super();
this.id = id;
this.name = name;
this.price = price;
}
// getter()、setter()方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
// toString()方法
@Override
public String toString() {
return " [商品编号=" + id + ", 商品名称=" + name + ", 商品价格=" + price + "]";
}
// 要实现Comparable接口就要实现它的抽象方法compareTo()
public int compareTo(Goods o) {// 传入参数指定对象
// 将当前对象的价格与指定对象的价格进行比较
double price1 = this.getPrice();
double price2 = o.getPrice();
// 升序
// price1-price2返回的是一个double值 comparaTo()返回的是int值
// 所以要将double值转换为int值 方法是生成一个double对象调用intValue()方法取出它的整数部分 并将它赋给变量n
int n = new Double(price1 - price2).intValue();
return n;
}
}
【测试类】
package com.jinglan.sort;
import java.util.*;
public class GoodsTest {
public static void main(String[] args) {
// 创建商品对象
Goods g1 = new Goods("s001", "手机", 2000);
Goods g2 = new Goods("s001", "电冰箱", 5000);
Goods g3 = new Goods("s001", "电视机", 3000);
// 创建集合 指定集合中的元素类型为Goods对象
ArrayList<Goods> list = new ArrayList<Goods>();
// 将商品对象添加到集合中去
list.add(g1);
list.add(g2);
list.add(g3);
// 排序前
System.out.println("排序前:");
for (Goods goods : list) {
System.out.println(goods);
}
// 排序后
System.out.println("排序后:");
Collections.sort(list);// 调用Comllections.sort()方法这个方法不需要传入比较器
for (Goods goods : list) {
System.out.println(goods);
}
}
}
【运行结果】
同样的如果想要实现降序排序只需要将compareTo()方法中当前对象price1和指定对象price2的位置进行调换即可
将这句代码
int n = new Double(price1 - price2).intValue();
改为:
int n = new Double(price2 - price1).intValue();
【运行结果】
对上面的知识进行一个简单总结:集合(collection)或者数组(array)中对于基本数据类型和字符串类型的排序, 只需要Collections.sort()方法或者Array.sort() 即可将元素进行一个升序排列 对于自定义的对象进行排序 则需要 去实现一个接口Comparable,并且重写其中的compareTo()方法在方法中自定义排序规则。
针对上面的知识扩展一个练习题
【例题】
分析:
1、一个Employee类有一些属性去实现Comparable接口并在接口中定义比较规则
2、一个EmployeeTest测试类去测试功能,定义一个集合将对象传入集合中,调用collections.sort()方法进行排序
【Employee类】
package com.jinglan.sort;
public class Employee implements Comparable<Employee> {// 实现Comparable接口
private String id;// 员工编号
private String name;// 员工姓名
private float salary;// 员工薪水
public Employee(String id, String name, float salary) {
super();
this.id = id;
this.name = name;
this.salary = salary;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
@Override
public String toString() {
return "员工 [编号=" + id + ", 姓名=" + name + ", 工资=" + salary + "]";
}
// 实现compareTo()方法
public int compareTo(Employee o) {
float salary1 = this.getSalary();// 当前对象
float salary2 = o.getSalary();// 指定对象
int n = (int) (salary1 - salary2);// 将float类型强转为int类型
return n;
}
}
【EmployeeTest类】
package com.jinglan.sort;
import java.util.*;
public class EmployeeTest {
public static void main(String[] args) {
// 创建Employee对象
Employee e1 = new Employee("emp001", "张三", (float) 1800.0);
Employee e2 = new Employee("emp002", "李四", (float) 2500.0);
Employee e3 = new Employee("emp003", "王五", (float) 1600.0);
// 创建集合指定集合中存储的类型为Employee对象
ArrayList<Employee> list = new ArrayList<Employee>();
// 向集合中添加对象
list.add(e1);
list.add(e2);
list.add(e3);
// 排序前
System.out.println("排序前:");
for (Employee emp : list) {
System.out.println(emp);
}
// 排序后
System.out.println("排序后");
Collections.sort(list);
for (Employee emp : list) {
System.out.println(emp);
}
}
}
【运行结果】
码不下了 太多了 后面还有 Comparator接口与Comparable接口的区别以及CompareTo()方法的介绍
请转到:Comparator接口与Comparable接口的区别以及compareTo()方法的介绍