Java编程语法——compartator在sort中的使用

本文深入探讨了Java中用于比较对象的两种主要方法:通过实现Comparable接口来赋予类天然的比较能力,以及通过创建实现Comparator接口的独立类来定制比较逻辑。文章通过具体例子展示了如何实现和应用这两种方法,并解决了一个排序问题,即根据成绩、姓名字母序和年龄对学生成绩进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java中有两种方式来提供比较功能!

  1. 实现java.lang.Comparable接口,使类具有“天生”的比较能力。此接口很简单,只有public int compareTo(Object obj)一个方法(注意在具体使用时Object可以替换为具体的类)。此方法接收一个Object作为参数,如果当前对象(this)小于参数obj则返回负值,如果相等则返回0,如果当前对象大于参数则返回正值。在使用时由于类本身就具有比较功能,所以直接sort就行了。
  2. 创建一个实现了Comparator接口的单独的类。尽管这个类由compare和equals两个方法。但因为无论何时创建一个类,都是间接继承自Object,而Object带有equals方法,所以如果不是有特殊的性能需要,不必实现equals方法。注意这里要实现的是compare方法,而不是第一种方式下的compareTO方法,格式如下:
    class MyCmp implements Comparator< CompType >{
    public int compare(CompType o1,CompType o2){
    ””
    //CompType是待比较的数据的类型
    //注意return的是一个整型
    }
    }
    由于是一个类,new一个对象,然后将其作为一个参数传到Arrays.sort()里实现排序功能!

    题目:

题目描述:

    有N个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名字符的字母序排序,如果姓名的字母序也相
    同则按照学生的年龄排序,并输出N个学生排序后的信息。

输入:

    测试数据有多组,每组输入第一行有一个整数N(N<=1000),接下来的N行包括N个学生的数据。
    每个学生的数据包括姓名(长度不超过100的字符串)、年龄(整形数)、成绩(小于等于100的正数)。

输出:

    将学生信息按成绩进行排序,成绩相同的则按姓名的字母序进行排序。
    然后输出学生信息,按照如下格式:
    姓名 年龄 成绩

样例输入:

3
abc 20 99
bcd 19 97
bed 20 97

样例输出:

bcd 19 97
bed 20 97
abc 20 99

提示:

学生姓名的字母序区分字母的大小写,如A要比a的字母序靠前(因为A的ASC码比a的ASC码要小)。

使用第一种方法:


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

class Student implements Comparable<Student>{
    public String name;
    public int age;
    public double grade;
    public int compareTo(Student otherStudent) {
        // TODO Auto-generated method stub
        if(this.grade!=otherStudent.grade){
            if(this.grade>otherStudent.grade) return 1;
            else return -1;
        }
        else if(!this.name.equals(otherStudent.name))return this.name.compareTo(otherStudent.name);
        return this.age - otherStudent.age;
    }

}

/**
 * 
        有N个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名字符的字母序排序,如果姓名的字母序也相
        同则按照学生的年龄排序,并输出N个学生排序后的信息。
 * */
class Mycmp implements Comparator<Student>{

    public int compare(Student o1,Student o2) {
        // TODO Auto-generated method stub
        if(o1.grade!=o2.grade){
            if(o1.grade>o2.grade) return 1;
            else return -1;
        }
        else if(!o1.name.equals(o2.name))return o1.name.compareTo(o2.name);
        return o1.age - o2.age;
    }
}

public class Main {

    public static void main(String[] args) {  
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            int N = in.nextInt();
            Student[] students = new Student[N+10];
            for(int i=0;i<N;i++){
                students[i] = new Student();
                students[i].name = in.next();
                students[i].age = in.nextInt();
                students[i].grade = in.nextDouble();
            }
            Arrays.sort(students,0,N);
            for(int i=0;i<N;i++){
                System.out.println(students[i].name+" "+students[i].age+" "+students[i].grade);
            }
        }
    }  
}  

使用第二种方法:


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

class Student{
    public String name;
    public int age;
    public double grade;
}

class Mycmp implements Comparator<Student>{

    public int compare(Student o1,Student o2) {
        // TODO Auto-generated method stub
        if(o1.grade!=o2.grade){
            if(o1.grade>o2.grade) return 1;
            else return -1;
        }
        else if(!o1.name.equals(o2.name))return o1.name.compareTo(o2.name);
        return o1.age - o2.age;
    }
}

public class Main {

    public static void main(String[] args) {  
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            int N = in.nextInt();
            Student[] students = new Student[N+10];
            for(int i=0;i<N;i++){
                students[i] = new Student();
                students[i].name = in.next();
                students[i].age = in.nextInt();
                students[i].grade = in.nextDouble();
            }
            Arrays.sort(students,0,N,new Mycmp());
            for(int i=0;i<N;i++){
                System.out.println(students[i].name+" "+students[i].age+" "+students[i].grade);
            }
        }
    }  
}  

注意这两种方式实现的接口不同,接口要实现的方法也不同。
1.如果要类“天生”具有比较能力,实现comparable接口(很形象,形容词,说明这是一个具有比较能力的类),而要实现的方法则是只有一个参数的compareTo方法
2.如果是创建一个实现Comparator接口的单独的类,则implements的接口是comparator接口,实现的比较方法是有两个参数的compare方法。
3.注意一个类就算它实现了Comparable接口,在sort是依然可以传入另一个实现了comparator的类的对象,两者不会冲突。
4.implements是一个类实现一个接口用的关键字,它是用来实现接口中定义的抽象方法。
实现一个接口,必须实现接口中的所有方法。
5.升序,降序
public int compare(Object o1, Object o2) 返回一个基本类型的整型
如果要按照升序排序,则o1 小于o2,返回-1(负数),相等返回0,01大于02返回1(正数)《=》return o1 - o2;
如果要按照降序排序则o1 小于o2,返回1(正数),相等返回0,01大于02返回-1(负数)《=》return o2 - o1;
test:


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

class A{
    public int x,y;
}

class Mycmp implements Comparator<A>{
    //按x升序,y降序
    public int compare(A a,A b){
        if(a.x!=b.x) return a.x-b.x;
        else return b.y - a.y;
    }
}
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        A[] arr = new A[5];
        for(int i=0;i<5;i++){
            arr[i] = new A();
            arr[i].x = in.nextInt();
            arr[i].y = in.nextInt();
        }
        Arrays.sort(arr, new Mycmp());
        for(A a:arr){
            System.out.println(a.x+","+a.y);
        }
    }

}

class Student implements Comparable<Student>{

    int id;
    public Student(int id) {
        // TODO Auto-generated constructor stub
        this.id = id;
    }
    @Override
    public int compareTo(Student o) {
        // TODO Auto-generated method stub
        return this.id - o.id;
    }
}

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Student[] stu = new Student[10];
        Random rand = new Random();
        for(int i=0;i<10;i++){
            stu[i] = new Student(rand.nextInt(100));
        }
        //在类里声明一个,直接作为比较器传到sort里,不过好像必须是非基本类才能这么用
        Comparator<Student> cmp = new Comparator<Student>() {

            @Override
            public int compare(Student o1, Student o2) {
                // TODO Auto-generated method stub
                return o2.id - o1.id;
            }
        };
        Arrays.sort(stu);
        for(Student x:stu){
            System.out.println(x.id);
        }
        System.out.println("ffffff");
        Arrays.sort(stu,cmp);
        for(Student x:stu){
            System.out.println(x.id);
        }
    }

}
### Comparator设计中的Virtuoso工具应用 在Cadence软件环境中,Virtuoso是一款广泛应用于模拟集成电路设计的强大平台。对于比较器(Comparator)的设计而言,该环境提供了全面的支持。 #### 设计流程概述 利用Virtuoso进行比较器电路设计通常遵循RTL到GDSII的设计流程[^2]。这包括但不限于版图规划(floor planning),电源网格设计(power grid design),布局布线(place and route),时钟树综合(clock tree synthesis),以及最终的时间收敛(timing closure)和电迁移/电压降分析(EM/IR drop analysis)。 #### 使用Virtuoso的具体步骤 针对比较器这样的特定功能模块,在Virtuoso内的操作可以分为几个方面: - **原理图输入(Schematic Entry)** 用户可以在图形界面下通过拖拽元件并连接它们来构建比较器的逻辑结构。此过程允许设计师直观地定义各个晶体管和其他组件之间的关系。 - **参数化单元(Parameterized Cells, PCells)** 对于某些类型的比较器,可能需要用到预设好的PCell库文件,这些文件包含了经过优化的标准单元模型,可以直接调用以加快开发速度。 - **仿真验证(Simulation Verification)** 完成初步设计之后,借助Spectre等内置仿真器执行直流(DC)、交流(AC)、瞬态(transient)等多种模式下的性能测试,确保满足预期的功能指标。 - **物理实现(Physical Implementation)** 当设计方案稳定并通过所有必要的检验后,则进入实际制造前的最后一环——即从抽象的概念转化为具体的几何形状描述,也就是我们所说的GDSII格式数据输出阶段。 ```tcl # 创建一个新的项目目录用于保存工作成果 create_project -path ./comparator_proj # 加载所需的工艺技术文件和技术库 set_tech_library /path/to/process_file.tf load_liberty_file /path/to/stdcell.lib # 开始绘制比较器的顶层原理图 open_schematic top_comparator # 添加差分对、电流源等基本构件至当前编辑窗口内... add_component diff_pair nmos_180nm add_component current_source pmos_180nm # 进行连线配置使各部分形成完整的比较器架构... # 执行DC扫描曲线测量作为初次功能性确认手段之一 run_dc_analysis top_comparator # 若一切正常则继续深入其他类型仿真实验直至完全达标为止... ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值