Java - Collections.sort() 问题
Java - Issue with Collections.sort()
我目前正在编写一个打印书籍 ArrayList 的程序。每个 ArrayList of books 元素都包含一个字符串(书名)和一个 ArrayList(该书的作者)。我需要对我的 ArrayList 书籍进行排序,以便它们按字母顺序显示(按标题排序)。我的问题是,当我打印新的 ArrayList(我调用 Collections.sort() 的列表)时,我得到的输出与我第一次打印 non-sorted 版本时相同。
我正在从我的 driver 程序调用 myLib.sort();
,该程序转到我的库中的这个方法 class:
public void sort()
{
Collections.sort(myBooks);
}
myBooks
就是我前面提到的书籍的ArrayList。根据我的阅读,Collections.sort("ArrayList name")
应该按字母顺序对我的列表进行排序。如果那不正确并且我需要使用 compareTo()
和 equals()
方法,那么这里是出现在 class Book
中的那些方法,我用它们来构建进入我的 [=] 的书籍22=]:
public int compareTo(final Book theOther)
{
int result = 0;
if (myTitle.equals(theOther.myTitle))
{
if (myAuthors.get(0) != theOther.myAuthors.get(0))
{
result = 1;
}
}
else
{
result = 0;
}
return result;
}
public boolean equals(final Object theOther)
{
if (theOther instanceof String)
{
String other = (String) theOther;
return myTitle == other;
}
else
{
return false;
}
}
我能想到的唯一可能的问题是我的打印方法。我的 driver 程序打印 myLib
这是一个库。我的图书馆 class 有以下 toString()
方法:
public String toString()
{
String result = "";
for (int i = 0; i < myBooks.size(); i++)
{
String tempTitle = myBooks.get(i).getTitle();
ArrayList<String> tempAuthors = myBooks.get(i).getAuthors();
Book tempBook = new Book(tempTitle, tempAuthors);
result += (tempBook + "\n");
}
return result;
}
这从我的书 class toString()
中获取每本书和那本书的字符串,方法如下:
public String toString()
{
return "\"" + myTitle + ",\" by " + myAuthors;
}
如果这太少、太多、太混乱、不够清楚等等...请在评论中告诉我,我会尽快编辑 post。如果需要,我也可以 post 我的三个 classes 的全部。我是 Java 的新手,也是 posting 的新手,所以我还在习惯这两种情况下的工作方式,所以如果您能对我宽容一点,我将不胜感激。谢谢!
您的 compareTo() 方法似乎有误,请注意 Collections.sort() 使用该方法比较列表中的 object。
你只检查标题是否相等,如果相等,那么你比较第一作者,如果它们相等你 return 1,否则你 return 0;
compareTo() 用于检查此 object 是否 less、equals 或 greater 比您要比较的那个(returning 0 表示等于,负数表示较小,正数表示较大,您 return 要么是正数,要么是 0)。我建议您阅读 compareTo()
方法的 javadoc。
这里的示例是 Book
class 的实现,其中我只根据标题进行比较(我省略了作者列表的比较)。
public class Book implements Comparable<Book> {
private String title;
private List<String> authors;
public Book(String title) {
this.title = title;
}
public int compareTo(Book o) {
return this.title.compareTo(o.title);
}
@Override
public boolean equals(Object b){
if(!(b instanceof Book)){
return false;
}
//authors comparison omitted
return this.title.equals(((Book) b).title);
}
@Override
public String toString(){
return "Title: "+ title; //todo: add authors also if need
}
}
正如您在 Book.compareTo() 方法中看到的那样,我依赖于 String.compareTo()。
它将 return -1、0 或 1;如果您需要根据作者列表进行比较,您还必须了解该方法的逻辑并考虑一些问题:
- 如果仅依赖列表中的第一作者就足够了
- 如果您需要确保作者列表已排序
- 如果作者列表为空会怎样
另外注意:compareTo
应该与equals
一致,这意味着如果compareTo returns 0 then equals should return 正确,反之亦然。
根据documentation,你还应该return负值:
Returns a negative integer, zero, or a positive integer as this object is less
than, equal to, or greater than the specified object.
public int compareTo(final Book theOther) {
int result = myTitle.compareTo(theOther.myTitle);
if (result == 0) {
result = myAuthors.get(0).compareTo(theOther.myAuthors.get(0));
}
return result;
}
检查@flowryn for better answer, as he also mention about equals()
according to the documentation:
It is strongly recommended, but not strictly required that
(x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class
that implements the Comparable interface and violates this condition
should clearly indicate this fact. The recommended language is "Note:
this class has a natural ordering that is inconsistent with equals."
我目前正在编写一个打印书籍 ArrayList 的程序。每个 ArrayList of books 元素都包含一个字符串(书名)和一个 ArrayList(该书的作者)。我需要对我的 ArrayList 书籍进行排序,以便它们按字母顺序显示(按标题排序)。我的问题是,当我打印新的 ArrayList(我调用 Collections.sort() 的列表)时,我得到的输出与我第一次打印 non-sorted 版本时相同。
我正在从我的 driver 程序调用 myLib.sort();
,该程序转到我的库中的这个方法 class:
public void sort()
{
Collections.sort(myBooks);
}
myBooks
就是我前面提到的书籍的ArrayList。根据我的阅读,Collections.sort("ArrayList name")
应该按字母顺序对我的列表进行排序。如果那不正确并且我需要使用 compareTo()
和 equals()
方法,那么这里是出现在 class Book
中的那些方法,我用它们来构建进入我的 [=] 的书籍22=]:
public int compareTo(final Book theOther)
{
int result = 0;
if (myTitle.equals(theOther.myTitle))
{
if (myAuthors.get(0) != theOther.myAuthors.get(0))
{
result = 1;
}
}
else
{
result = 0;
}
return result;
}
public boolean equals(final Object theOther)
{
if (theOther instanceof String)
{
String other = (String) theOther;
return myTitle == other;
}
else
{
return false;
}
}
我能想到的唯一可能的问题是我的打印方法。我的 driver 程序打印 myLib
这是一个库。我的图书馆 class 有以下 toString()
方法:
public String toString()
{
String result = "";
for (int i = 0; i < myBooks.size(); i++)
{
String tempTitle = myBooks.get(i).getTitle();
ArrayList<String> tempAuthors = myBooks.get(i).getAuthors();
Book tempBook = new Book(tempTitle, tempAuthors);
result += (tempBook + "\n");
}
return result;
}
这从我的书 class toString()
中获取每本书和那本书的字符串,方法如下:
public String toString()
{
return "\"" + myTitle + ",\" by " + myAuthors;
}
如果这太少、太多、太混乱、不够清楚等等...请在评论中告诉我,我会尽快编辑 post。如果需要,我也可以 post 我的三个 classes 的全部。我是 Java 的新手,也是 posting 的新手,所以我还在习惯这两种情况下的工作方式,所以如果您能对我宽容一点,我将不胜感激。谢谢!
您的 compareTo() 方法似乎有误,请注意 Collections.sort() 使用该方法比较列表中的 object。
你只检查标题是否相等,如果相等,那么你比较第一作者,如果它们相等你 return 1,否则你 return 0;
compareTo() 用于检查此 object 是否 less、equals 或 greater 比您要比较的那个(returning 0 表示等于,负数表示较小,正数表示较大,您 return 要么是正数,要么是 0)。我建议您阅读 compareTo()
方法的 javadoc。
这里的示例是 Book
class 的实现,其中我只根据标题进行比较(我省略了作者列表的比较)。
public class Book implements Comparable<Book> {
private String title;
private List<String> authors;
public Book(String title) {
this.title = title;
}
public int compareTo(Book o) {
return this.title.compareTo(o.title);
}
@Override
public boolean equals(Object b){
if(!(b instanceof Book)){
return false;
}
//authors comparison omitted
return this.title.equals(((Book) b).title);
}
@Override
public String toString(){
return "Title: "+ title; //todo: add authors also if need
}
}
正如您在 Book.compareTo() 方法中看到的那样,我依赖于 String.compareTo()。 它将 return -1、0 或 1;如果您需要根据作者列表进行比较,您还必须了解该方法的逻辑并考虑一些问题:
- 如果仅依赖列表中的第一作者就足够了
- 如果您需要确保作者列表已排序
- 如果作者列表为空会怎样
另外注意:compareTo
应该与equals
一致,这意味着如果compareTo returns 0 then equals should return 正确,反之亦然。
根据documentation,你还应该return负值:
Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
public int compareTo(final Book theOther) {
int result = myTitle.compareTo(theOther.myTitle);
if (result == 0) {
result = myAuthors.get(0).compareTo(theOther.myAuthors.get(0));
}
return result;
}
检查@flowryn for better answer, as he also mention about equals()
according to the documentation:
It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."