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 是否 lessequalsgreater 比您要比较的那个(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."