java Comparable接口与Comparator接口的使用与区别

一、Comparable 接口的使用

Comparable 这个接口对实现它的每个类的对象施加了一个总的排序。这个顺序被称为类的自然排序,和类的compareTo方法称为自然方法。

 实现这个接口的可以自动排序的对象列表(list<>)或数组(Object[])可以通过 Collections.sort()或Arrays.sort()方法进行排序。

实现此接口的对象中的元素可以作为排序集中的进行比较的键,而不需要指定比较器。(上述为翻译API中的一段话)。

因为刚好用到排序,并且是需要对整体进行排序可以使用 Comparable  接口。

1、需要进行排序的 pojo 对象需要实现  Comparable  接口,实现自定义的排序方法。

最终的目的:对  Staff 对象,按照对象的年龄属性,与KPI属性的大小进行排序。年龄大的排在前面,年龄相同的 则KPI 高的排在前面

package comparable_test;

/**
 * 员工实体
 * @author Scott
 * @time 2017年9月9日
 */
public class Staff implements Comparable<Staff>{
	
	/** 员工年龄*/
	private int age;
	/** 员工KPI*/
	private int score;
	
	/**
	 * 构造函数
	 * @param age
	 * @param score
	 */
	public Staff(int age, int score) {
		super();
		this.age = age;
		this.score = score;
	}
	
	//比较对象大小时以 参数 作为基准
	@Override
	public int compareTo(Staff o) {
		int i = 0;
		if (o.age > this.age) {
			i = 1;
		} else if (this.age == o.age) {
			if (o.score > this.score) {
				i = 1;
			} else if (o.score < this.score) {
				i = -1;
			} 
		} else if (o.age < this.age) {
			i = -1;
		}
		return i;
	}
	
	//get set ...
	
	public int getScore() {
		return score;
	}
	
	public void setScore(int score) {
		this.score = score;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
}


2、使用Collections.sort()方法进行整体排序,并输出排序前后的结果

此时是不许要指定一个比较器的
package comparable_test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestSort {
	
	static List<Staff> staffInfos = new ArrayList<Staff>();
	public static void main(String[] args) {
		
		staffInfos.add(new Staff(5, 102));
		staffInfos.add(new Staff(8, 103));
		staffInfos.add(new Staff(4, 104));
		staffInfos.add(new Staff(4, 105));
		
		//排序前输出结果
		System.out.println("排序前输出结果");
		staffInfos.forEach(staff -> {
			int age = staff.getAge();
			int score = staff.getScore();
			System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
		});
		
		//排序后输出结果
		System.out.println("\n"+"排序后输出结果");
		Collections.sort(staffInfos);
		staffInfos.forEach(staff -> {
			int age = staff.getAge();
			int score = staff.getScore();
			System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
		});
		
	}
}

3、排序前后输出结果对比

排序前输出结果
年龄:5 KPI:102
年龄:8 KPI:103
年龄:4 KPI:104
年龄:4 KPI:105

排序后输出结果
年龄:8 KPI:103
年龄:5 KPI:102
年龄:4 KPI:105
年龄:4 KPI:104

通过上面的排序前后的输出结果看到,已经实现了之前的目的了。只要pojo类实现了 Comparable  接口,如果是 List<> 则使用 Collections.sort(); 方法进行排序。如果是Staff[]数组,则使用Arrays.sort()进行排序。
这里面说明一下:使用 Comparable 接口实现整体排序时,需要注意的是排序是以被实现的  compareTo () 方法中的参数为基准的。具体请各位读者自己测试。

二、Comparator接口的使用

1、需要进行整体排序的对象如下
package comparable_test;

/**
 * 员工实体
 * @author Scott
 * @time 2017年9月9日
 */
public class Staff {
	
	/** 员工年龄*/
	private int age;
	/** 员工KPI*/
	private int score;
	
	/**
	 * 构造函数
	 * @param age
	 * @param score
	 */
	public Staff(int age, int score) {
		super();
		this.age = age;
		this.score = score;
	}
	
	//get set ...
	
	public int getScore() {
		return score;
	}
	
	public void setScore(int score) {
		this.score = score;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
}

2、使用 Comparator 接口对上面的 staff 进行整体排序

在使用 Comparator 接口实现整体排序时,需要实现自定义的比较器。
在使用 Collections.sort()或Arrays.sort() 进行排序时需要指定使用哪个比较器

package comparable_test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
 * 测试类
 * @author Scott
 * @time 2017年9月11日
 */
public class TestSort {
	
	/** Staff 列表*/
	static List<Staff> staffInfos = new ArrayList<Staff>();
	
	public static void main(String[] args) {
		staffInfos.add(new Staff(5, 102));
		staffInfos.add(new Staff(8, 103));
		staffInfos.add(new Staff(4, 104));
		staffInfos.add(new Staff(4, 105));
		//排序前输出结果
		System.out.println("排序前输出结果");
		staffInfos.forEach(staff -> {
			int age = staff.getAge();
			int score = staff.getScore();
			System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
		});
		
		//使用  Comparator 构造自定义比较器
		Comparator<Staff> comparaor = new Comparator<Staff>() {
			@Override
			public int compare(Staff o1, Staff o2) {
				int i = 0;
				if (o2.getAge() > o1.getAge()) {
					i = 1;
				} else if (o2.getAge() == o1.getAge()) {
					if (o2.getScore() > o1.getScore()) {
						i = 1;
					} else if (o2.getScore() < o1.getScore()) {
						i = -1;
					}
				} else if (o2.getAge() < o1.getAge()) {
					i = -1;
				}
				return i;
			}
		};
		//进行排序,第二个参数是指定使用的比较器
		Collections.sort(staffInfos, comparaor);
		
		//排序后输出结果
		System.out.println("\n"+"排序后输出结果");
		staffInfos.forEach(staff -> {
			int age = staff.getAge();
			int score = staff.getScore();
			System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
		});
	}
}

3、使用 Comparator 进行整体排序的输出结果

排序前输出结果
年龄:5 KPI:102
年龄:8 KPI:103
年龄:4 KPI:104
年龄:4 KPI:105


排序后输出结果
年龄:8 KPI:103
年龄:5 KPI:102
年龄:4 KPI:105
年龄:4 KPI:104

三、使用 Comparable 与 Comparator 两者的区别

从上面两个简答的使用例子中可以发现:
使用 Comparable 与 Comparator 两者的区别是:
 * 1、使用 Comparable 在需要进行整体排序的类中 需要实现 Comparable 接口,实现接口中的 compareTo() 方法(比较器)。使用 Comparator 则不需要实现任何接口
 * 2、使用 Comparator 需要自定义比较器,在排序时(使用Collections.sort()方法进行排序)需要指定比较器。而使用 Comparable 接口在排序时则不需要指定比较器


猜你喜欢

转载自blog.csdn.net/wgs_93/article/details/77916508