实现Comparable接口和Comparator接口

声明一个Employee员工类,包含编号、姓名、薪资,实现Comparable接口,要求,按照薪资比较大小,如果薪资相同,按照编号比较大小。

声明一个测试类TestEmployee类,在main中创建Employee[]数组,长度为5,并且存储5个员工对象,现在要求用冒泡排序,实现对这个数组进行排序,遍历结果。

练习1:

声明一个Employee员工类,包含编号、姓名、薪资,实现Comparable接口,要求,按照薪资比较大小,如果薪资相同,按照编号比较大小。

声明一个测试类TestEmployee类,在main中创建Employee[]数组,长度为5,并且存储5个员工对象,现在要求用冒泡排序,实现对这个数组进行排序,遍历结果。

public class Employee implements Comparable{
    private int id;
    private String name;
    private int salay;

    public Employee() {
    }

    public Employee(int id, String name, int salay) {
        this.id = id;
        this.name = name;
        this.salay = salay;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSalay() {
        return salay;
    }

    public void setSalay(int salay) {
        this.salay = salay;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", salay=" + salay +
                '}';
    }

    @Override
    public int compareTo(Object o) {
        Employee ee = (Employee) o;
        if(this.salay != ee.salay){
            return this.salay - ee.salay;
        }else{
//            if(this.id > ee.id)
            return this.id - ee.id;
        }
    }
}

测试类:

package ed.hfuu.interface1;

import java.util.Arrays;

public class TestEE {
    public static void main(String[] args) {
        Employee[] employees = new Employee[5];

        employees[0] = new Employee(1, "abc", 10000);
        employees[1] = new Employee(2, "abc", 100);
        employees[2] = new Employee(3, "abc", 1000);
        employees[3] = new Employee(4, "abc", 10000);
        employees[4] = new Employee(5, "abc", 1000000);

        for(int i = 0; i < employees.length - 1; i++){
            for(int j = 0; j < employees.length - 1 - i; j++){
                if(employees[j].compareTo(employees[j + 1]) > 0){
                    Employee eeTemp = employees[j];
                    employees[j] = employees[j + 1];
                    employees[j + 1] = eeTemp;
                }
            }
        }

        for (Employee employee : employees) {
            System.out.println(employee.toString());
        }

    }
}
练习2:自定义数组排序工具类

自定义一个数组工具类MyArrays,它包含一个静态方法,可以给任意对象数组用冒泡排序实现从小到大排序,该怎么定义这个方法呢?
注意:这里数组元素对象必须实现了comparable接口,否则会发生 ClassCastException。如这里测试的Employee类就实现了Comparable接口(如上例)。

class MyArrays{
	public static void sort(Object[] arr){
		//冒泡排序
		for (int i = 1; i < arr.length; i++) {
			for (int j = 0; j < arr.length-i; j++) {
				//将arr[j]强制为Comparable接口类型,目的是调用compareTo方法
				//当然如果数组的元素没有实现这个接口,那么将会发生ClassCastException
				Comparable c = (Comparable) arr[j];
				if(c.compareTo(arr[j+1])>0){
					Object temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
	}
}

java.util.Arrays数组工具类的public static void sort(Object[] a)就是这么实现的,只不过它使用的排序算法是效率更高快排,而不是冒泡排序,但是无论哪种排序算法,最终都要涉及到两个元素的比较大小,都需要通过元素调用compareTo()方法。

思考:

(1)如果一个类,没有实现 Comparable接口,而这个类你又不方便修改(例如:一些第三方的类,你只有.class文件,没有源文件),那么这样类的对象也要比较大小怎么办?

(2)如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?

JDK在设计类库之初,也考虑到这种情况了,所以又增加了一个java.util.Comparator接口。

package java.util;

public interface Comparator{
    int compare(Object o1,Object o2);
}

那么我们想要比较某个类的两个对象的大小,怎么做呢?步骤:

第一步:编写一个类,我们称之为比较器类型,实现java.util.Comparator接口,并重写方法

  • 方法体就是你要如何指定的两个对象的大小

第二步:比较大小时,通过比较器类型的对象调用compare()方法,将要比较大小的两个对象作为compare方法的实参传入,根据方法的返回值决定谁大谁小。

  • o1对象大于o2返回正整数
  • o1对象小于o2返回负整数
  • o1对象等于o2返回零

代码示例:一个没有实现Comparable接口的学生类

class Student{
	private String name;
	private int score;
	public Student(String name, int score) {
		super();
		this.name = name;
		this.score = score;
	}
	public Student() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getScore() {
		return score;
	}
	public void setScore(int score) {
		this.score = score;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", score=" + score + "]";
	}
	
}

代码示例:定义定制比较器类

class StudentScoreCompare implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		Student s1 = (Student) o1;
		Student s2 = (Student) o2;
		return s1.getScore() - s2.getScore();
	}
	
}

代码示例:测试类

import java.util.Comparator;

public class TestComparator {
	public static void main(String[] args) {
		Student stu1 = new Student("张三",89);
		Student stu2 = new Student("李四",78);
		
		StudentScoreCompare ssc = new StudentScoreCompare();
		if(ssc.compare(stu1, stu2)>0){
			System.out.println(stu1 + ">" + stu2);
		}else if(ssc.compare(stu1, stu2)<0){
			System.out.println(stu1 + "<" + stu2);
		}else{
			System.out.println(stu1 + "=" + stu2);
		}
	}
}
练习1:冒泡排序

声明一个Employee员工类,包含编号、姓名、薪资,

声明一个测试类,在main中,创建Employee[]数组,长度为5,显示原来顺序结果

声明一个定制比较器EmpSalaryComparator,实现Comparator接口,按照薪资比较大小

声明一个定制比较器EmpIdComparator,实现Comparator接口,按照编号比较大小

在测试类中,分别用这个两个比较器对象,对数组进行排序,并显示排序后结果

员工类示例代码:

class Employee{
	private int id;
	private String name;
	private double salary;
	public Employee(int id, String name, double salary) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
	}
	public Employee() {
		super();
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	@Override
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + "]";
	}
}

员工薪资定制比较器类型:

class EmpSalaryComparator implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		Employee e1 = (Employee) o1;
		Employee e2 = (Employee) o2;
		return Double.compare(e1.getSalary(), e2.getSalary());
	}
	
}

员工编号定制比较器类型:

class EmpIdComparator implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		Employee e1 = (Employee) o1;
		Employee e2 = (Employee) o2;
		return e1.getId() - e2.getId();
	}
	
}

测试类示例代码:

import java.util.Comparator;

public class TestComparator {
	public static void main(String[] args) {
		Employee[] arr = new Employee[5];
		arr[0] = new Employee(1,"张三",13000);
		arr[1] = new Employee(3,"王五",14000);
		arr[2] = new Employee(2,"李四",13000);
		arr[3] = new Employee(4,"赵六",7000);
		arr[4] = new Employee(5,"钱七",9000);
		
		//原顺序
		System.out.println("员工列表:");
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
		
		EmpSalaryComparator ec = new EmpSalaryComparator();
		//冒泡排序
		for (int i = 1; i < arr.length; i++) {
			for (int j = 0; j < arr.length-i; j++) {
				if(ec.compare(arr[j], arr[j+1])>0){
					Employee temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		
		System.out.println("按照薪资排序后员工列表:");
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
		
		EmpIdComparator ec2 = new EmpIdComparator();
		//冒泡排序
		for (int i = 1; i < arr.length; i++) {
			for (int j = 0; j < arr.length-i; j++) {
				if(ec2.compare(arr[j], arr[j+1])>0){
					Employee temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
				
		System.out.println("按照编号排序后员工列表:");
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
	}
}
练习2:自定义数组排序工具类

自定义一个数组工具类MyArrays,它包含一个静态方法,可以给任意对象数组用冒泡排序实现从小到大排序,该怎么定义这个方法呢?

class MyArrays{
	public static void sort(Object[] arr,Comparator c){
		//冒泡排序
		for (int i = 1; i < arr.length; i++) {
			for (int j = 0; j < arr.length-i; j++) {
				//这里不需要强制类型转换
				if(c.compare(arr[j], arr[j+1])>0){
					Object temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
	}
	
}

用新工具类,简化练习1测试类的代码

public class TestComparator {
	public static void main(String[] args) {
		Employee[] arr = new Employee[5];
		arr[0] = new Employee(1,"张三",13000);
		arr[1] = new Employee(3,"王五",14000);
		arr[2] = new Employee(2,"李四",13000);
		arr[3] = new Employee(4,"赵六",7000);
		arr[4] = new Employee(5,"钱七",9000);
		
		//原顺序
		System.out.println("员工列表:");
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
		
		EmpSalaryComparator ec = new EmpSalaryComparator();
		MyArrays.sort(arr, ec);
		
		System.out.println("按照薪资排序后员工列表:");
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
		
		EmpIdComparator ec2 = new EmpIdComparator();
		MyArrays.sort(arr, ec2);
				
		System.out.println("按照编号排序后员工列表:");
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
	}
}

java.util.Arrays数组工具类的public static void sort(T[] a, Comparator<? super T> c)就是这做的

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

人畜无害的萌新史莱姆

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值