集合的排序

集合排序原理:

对集合的排序可分为:基本数据类型排序和字符串排序
对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()方法的介绍

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

立志Java工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值