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);
时,会发生什么
代码片段仅用于演示目的
# 1 楼答案
你问了两个不同的问题,所以我将分别回答
第一个是,通过比较,我们想知道什么。名称比雷托(s.姓名)
当对Student类的对象调用compareTo方法时,this将成为调用对象。由于调用对象(希望)已正确初始化,因此此操作将失败。name将是调用对象的名称
s.name是传递给compareTo方法的学生对象的名称,该方法再次(希望)正确初始化并具有名称
归根结底是一个字符串变量调用compareTo传递一个字符串变量进行比较
第二个问题是当我们进行收集时真正发生的事情。排序(学生名单)
下面是Collections.Sort method上的JavaDocs,但是您可能会问,相对于您的Comparable的实现,它做了什么。简而言之,它在对排序进行比较时使用compareTo方法
# 2 楼答案
既然
name
似乎是Student
的一个重要属性,那么你首先应该问自己“什么是学生的有效名字?”null
有效吗?空字符串有效吗?如果不是,则需要使用setter防止使用无效的name
初始化Student
:现在,在构造函数中调用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
)。诀窍是如何做到这一点,以减少执行的比较次数。有很多很好的资料可以解释不同的排序方法,但归根结底,这都是因为能够比较元素并判断哪些元素应该在哪些元素之前出现