Java - Collections.sort()的问题

时间:2015-08-05 02:04:11

标签: java sorting arraylist collections tostring

我目前正在编写一个打印书籍ArrayList的程序。书籍元素的每个ArrayList由一个字符串(一本书的标题)和一个ArrayList(该书的作者)组成。我需要对书籍的ArrayList进行排序,使它们按字母顺序排列(按标题排序)。我的问题是,当我打印新的ArrayList(我称之为Collections.sort()的列表)时,我得到的输出与我第一次打印非排序版本时的输出相同。

我从我的驱动程序调用{​​{1}},该程序在我的库类中转到此方法:

myLib.sort();

public void sort() { Collections.sort(myBooks); } 是我前面提到的书籍的ArrayList。根据我的阅读,myBooks应按字母顺序对列表进行排序。如果这不正确,我需要使用Collections.sort("ArrayList name")compareTo()方法,那么这些方法就像equals()中出现的方法一样,用于构建进入class Book的书籍1}}:

class Library

我能想到的唯一剩下的可能问题是我的打印方法。我的驱动程序打印 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; } } 这是一个库。我的库类具有以下myLib方法:

toString()

这会从我的Book class 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; } 方法获取每本书和该书的字符串,如下所示:

toString()

如果这太小,太多,太混乱,不够清楚等等......请在评论中告诉我,我会尽快编辑帖子。如果需要,我也可以发布我的三个课程的全部内容。我是Java的新手,并且在发布时相当新,所以我仍然习惯于在两种情况下如何完成工作,所以如果你对我很轻松,我会很感激。谢谢!

2 个答案:

答案 0 :(得分:5)

您的compareTo()方法似乎有误,请注意Collections.sort()使用该方法来比较列表中的对象。

你只检查标题是否等于,如果是,那么你比较第一作者,如果它们相等则你返回1,否则你返回0;

compareTo()用于检查此对象是 等于还是更高,而不是您要比较的对象(返回0)是等于,负数为少,正数为大,你返回正数0)。我建议你阅读compareTo()方法的javadoc。

这里的示例是Book类的实现,我只根据标题进行比较(我省略了作者列表的比较)。

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()。 它将返回-1,0或1;如果您需要根据作者列表进行比较,您还必须了解该方法的逻辑并考虑一些问题:

  • 如果仅仅依靠名单上的第一位作者
  • 如果您需要确保作者列表已排序
  • 如果作者列表为空,会发生什么

同样注意compareTo应该与equals一致,这意味着如果compareTo返回0,那么equals应该返回true,反之亦然。

答案 1 :(得分:2)

根据documentation,您还应该返回负值:

  

返回负整数,零或正整数,因为此对象较小   比,等于或大于指定的对象。

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以获得更好的答案,因为他还根据documentation提到了equals()

  

强烈推荐,但并非严格要求   (x.compareTo(y)== 0)==(x.equals(y))。一般来说,任何课程   实现Comparable接口并违反此条件   应该清楚地表明这一事实。推荐的语言是“注意:   这个类的自然顺序与equals不一致。“