我对java有点新,对Collection框架来说还是新手。我知道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);
时,会发生什么?
代码段仅用于演示目的
答案 0 :(得分:4)
你问两个不同的问题,所以我会单独回答它们
第一个是我们通过比较this.name.compareTo(s.name);
尝试什么当在类Student的对象上调用compareTo方法时, this 成为调用对象。由于调用对象(希望)已经正确初始化,因此this.name将是调用对象的名称。
s.name是传递给compareTo方法的Student对象的名称,该方法再次(希望)正确初始化并具有名称。
什么是归结为一个String变量调用compareTo传入一个String变量来与
进行比较第二个是当我们做Collections.sort(studentList)时真正发生的事情;
以下是Collections.Sort method上的JavaDocs,但您可能会询问它与您的Comparable实现相关的功能。简而言之,它在进行排序
的比较时使用compareTo方法答案 1 :(得分:2)
由于似乎name
是Student
的重要属性,首先你要问自己的是“学生的名字是什么?” null
有效吗?空字符串有效吗?如果没有,则需要使用setter阻止使用无效Student
初始化name
:
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
值,则每次调用NullPointerException
方法时都会获得compareTo()
。你基本上是在调用null.compareTo()
,显然null
没有这样的方法,它没有任何方法。
现在,使用sort()
方法。你如何排序Student
?如果您没有告诉Java如何将一个Student
与另一个Student
进行比较,那么它应该如何排序?它可以处理数字(2小于3)和字符串(“a”在“b”之前),但它不知道如何比较您创建的自定义类。因此,您需要使用compareTo()
方法让它知道。在无法比较的对象集合上调用sort()
将导致异常。在sort()
集合上调用Student
将使用您在compareTo()
中提供的规则(name
(常规字符串比较))对其进行排序。
至于排序机制本身,它是特定于实现的,但它通常是几种算法的组合,一种混合。在Java中我相信它是Timsort
,在C#中它是内省的排序。在任何情况下,为了对这样的集合进行排序,您需要逐个比较元素(因此需要实现Comparable
)。诀窍是如何做到这一点,以减少执行比较的次数。有很多很好的资源来解释不同的排序方法,但这一切都归结为能够比较元素并告诉它应该在哪个之前。