有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么我们在可比较的实现中使用“this”?

我对java有些陌生,对集合框架也很陌生。我知道this指的是当前对象

public class Student implements Comparable <Student> {

    String name;
    int grade;

    public Student(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }
    public int compareTo(Student s) {
         return this.name.compareTo(s.name);
    }
    public String toString() {
        return this.name + ", " + this.grade;
    }
}

这里this.name是空的,并且s.name确实有一个值,那么我们通过比较this.name.compareTo(s.name);来尝试做什么呢

还有,当我们做Collections.sort(studentList);时,会发生什么

代码片段仅用于演示目的


共 (2) 个答案

  1. # 1 楼答案

    你问了两个不同的问题,所以我将分别回答

    第一个是,通过比较,我们想知道什么。名称比雷托(s.姓名)

    当对Student类的对象调用compareTo方法时,this将成为调用对象。由于调用对象(希望)已正确初始化,因此此操作将失败。name将是调用对象的名称

    s.name是传递给compareTo方法的学生对象的名称,该方法再次(希望)正确初始化并具有名称

    归根结底是一个字符串变量调用compareTo传递一个字符串变量进行比较

    第二个问题是当我们进行收集时真正发生的事情。排序(学生名单)

    下面是Collections.Sort method上的JavaDocs,但是您可能会问,相对于您的Comparable的实现,它做了什么。简而言之,它在对排序进行比较时使用compareTo方法

  2. # 2 楼答案

    既然name似乎是Student的一个重要属性,那么你首先应该问自己“什么是学生的有效名字?”null有效吗?空字符串有效吗?如果不是,则需要使用setter防止使用无效的name初始化Student

    public void setName(String name) {
      if (name is invalid) {
        throw error;
      }
    
      this.name = name; // name is valid, so this is safe now
    }
    

    现在,在构造函数中调用setter,您将确保如果您有一个Student,那么他将有一个有效的name

    使用无效的name的一个问题是,如果不阻止null值,则每次调用compareTo()方法时都会得到一个NullPointerException。实际上,您将调用null.compareTo(),显然null没有这样的方法,它没有任何方法

    现在,转到sort()方法。如何对Student进行排序?如果您不告诉Java如何比较一个Student和另一个Student,它应该如何排序?它可以处理数字(2小于3)和字符串(“a”在“b”之前),但它不知道如何比较您创建的自定义类。因此,您需要让它知道-使用compareTo()方法。对无法比较的对象集合调用sort()将导致异常。对Student集合调用sort()将使用compareTo()中提供的规则对它们进行排序,这是通过name(常规字符串比较)实现的

    至于排序机制本身,它是特定于实现的,但它通常是几种算法的组合,一种混合算法。在Java中,我相信它是{},在C#中,它是内省式的。在任何情况下,为了对这样的集合进行排序,您需要逐个比较元素(因此需要实现Comparable)。诀窍是如何做到这一点,以减少执行的比较次数。有很多很好的资料可以解释不同的排序方法,但归根结底,这都是因为能够比较元素并判断哪些元素应该在哪些元素之前出现