【JavaSE】---Comparable接口与Comparator
【JavaSE】---Comparable接口与Comparator比较器
一、Comparable接口
1、Comparable接口的定义
可以看出这个接口是通过泛型定义的,作用就是用来指定某一对象的排序规则的。
返回值:
1:表示大于
-1:表示小于
0:表示相等
2、实际案例
以下内容参考:
版权声明:本文为CSDN博主「南淮北安」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/nanhuaibeian/article/details/104169002
设计一个学生类,包含姓名、年龄、成绩,并产生一个对象数组,要求按成绩由高到底排序,如果成绩相等,则按年龄由低到高排序。
此时如果直接编写排序操作会比较麻烦,所以可以==使用 Arrays 类中的 sort() 方法进行排序操作。
import java.util.Arrays;
class Student implements Comparable<Student>{//指定类型为 Student
private String name;
private int age;
private float score;
public Student(String name,int age,float score){
this.name = name;
this.age = age;
this.score = score;
}
public String toString(){
return name + "\t\t" + age + "\t\t" + score;
}
public int compareTo(Student stu){
//覆写 compareTo() 方法,实现排序规则的应用
if (this.score>stu.score){
return -1;
}else if(this.score < stu.score){
return 1;
}else {
if (this.age > stu.age){
return 1;
}else if (this.age<stu.age){
return -1;
}else {
return 0;
}
}
}
}
public class Root{
public static void main(String[] args) {
Student[] stu = {new Student("stu1",20,90.0f),
new Student("stu2",22,90.0f),
new Student("stu3",20,70.0f),
new Student("stu4",34,98)};
Arrays.sort(stu);
for (Student x:stu){
System.out.println(x);
}
}
}
3、比较器的排序原理
这里博主写的太好了,忍不住做个笔记,抄下作业。
排序过程实际上就是数据结构中的二叉树排序方法,通过二叉树进行排序,然后利用中序遍历的方式把内容依次读取出来。
class BinaryTree{
class Node{//声明一个节点类
private Comparable data;//保存具体的内容
private Node left;
private Node right;
public void addNode(Node newNode){
//要确定是放在左子树还是右子树
if(newNode.data.compareTo(this.data)<0){
if(this.left == null){//放在左子树
this.left = newNode;
}else {
this.left.addNode(newNode);
}
}
if (newNode.data.compareTo(this.data)>=0){
if(this.right == null){ //放在右子树
this.right = newNode;
}else {
this.right.addNode(newNode);
}
}
}
public void printNode(){//输出时采用中序遍历
if (this.left != null){//先输出左子树
this.left.printNode();
}
System.out.print(this.data + "\t");//再输出根节点
if (this.right !=null){
this.right.printNode();
}
}
}
private Node root;
public void add(Comparable data){
Node newNode = new Node();//每传入一个新的内容就声明一个根节点
newNode.data = data;
if(root == null){
root = newNode;//如果是第1个元素,设置成根元素
}else{
root.addNode(newNode);//确定节点是放在左子树还是右子树
}
}
public void print(){//输出节点
this.root.printNode();
}
}
public class Test{
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.add(8);
bt.add(3);
bt.add(3);
bt.add(10);
bt.add(9);
bt.add(1);
bt.add(5);
bt.add(5);//加入重复元素
System.out.println("排序之后的结果:");
bt.print();
}
}
二、Comparator比较器
1、介绍
comparator
是javase
中的接口,位于java.util
包下,该接口抽象度极高,有必要掌握该接口的使用- 大多数文章告诉大家
comparator
是用来排序,但我想说排序是comparator
能实现的功能之一,他不仅限于排序
2、使用场景
- 排序,需要比较两个对象谁排在前谁排在后(排序也可以让类实现Comparable接口,实现后该类的实例也具有排序能力)。
- 分组,需要比较两个对象是否是属于同一组。
3、排序场景
在List或数组中的对象如果没有实现Comparable接口时,那么就需要调用者为需要排序的数组或List设置一个Compartor,Compartor的compare方法用来告诉代码应该怎么去比较两个实例,然后根据比较结果进行排序。
https://www.cnblogs.com/MrYuChen-Blog/p/14012428.html
4、但一条件排序
①Dog基类
public class Dog {
public int age;
public String name;
public String num;
public Dog(int age, String name, String num) {
this.age = age;
this.name = name;
this.num = num;
}
public Dog() {
}
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;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
@Override
public String toString() {
return "Dog{" +
"age=" + age +
", name='" + name + '\'' +
", num='" + num + '\'' +
'}';
}
}
②单一条件排序测试
import java.text.Collator;
import java.util.*;
public class OneSort {
public static void main(String[] args) {
List<Dog> dogList= new ArrayList<Dog>(){
{
add(new Dog(5, "DogA","001"));
add(new Dog(5, "DogB","002"));
add(new Dog(5, "DogC","003"));
add(new Dog(9, "DogA","004"));
add(new Dog(35, "DogF","005"));
add(new Dog(74, "DogG","006"));
}
};
test1(dogList);
System.out.println("给狗子按照年龄倒序:"+dogList);
test2(dogList);
System.out.println("给狗子按照名字排序:"+dogList);
}
/**
* 单一条件排序
*/
public static void test1(List a){
Collections.sort(a, new Comparator<Dog>() {
//实现compare(T o1, To2) 方法,返回正数,零,负数各代表大于,等于小于
@Override
public int compare(Dog o1, Dog o2) {
return o2.age - o1.age; //排序规则----升序
}
});
}
public static void test2(List a){
//按照名字排序
Collator comparator = Collator.getInstance(Locale.CANADA);
Collections.sort(a, new Comparator<Dog>() {
@Override
public int compare(Dog o1, Dog o2) {
return comparator.compare(o1.getName(),o2.getName());
}
});
}
}
③Lambda
/**
*使用Lambda表达式优化比较器代码(单一条件排序)
*/
@Test
public void test3() {
//对学生集合按年龄进行排序
Collections.sort(list,(s1, s2) -> (s1.getAge() - s2.getAge()) );
}
5、多条件排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SecondSort {
public static void main(String[] args) {
List<Dog> dogList= new ArrayList<Dog>(){
{
add(new Dog(5, "DogA","001"));
add(new Dog(5, "DogB","002"));
add(new Dog(5, "DogC","003"));
add(new Dog(9, "DogA","004"));
add(new Dog(35, "DogF","005"));
add(new Dog(74, "DogG","006"));
}
};
test1(dogList);
System.out.println("年龄多条件:"+dogList);
}
public static void test1(List a){
Collections.sort(a, new Comparator<Dog>() {
@Override
public int compare(Dog o1, Dog o2) {
int flag;
// 首选按年龄升序排序
flag = o1.getAge()-o2.getAge();
if(flag==0){
// 如果年龄按编号降序排序
flag = o2.getNum().compareTo(o1.getNum());
}
return flag;
}
});
}
}