为什么compareTo方法在排序对象数组时这么慢

时间:2014-03-21 19:22:32

标签: java arrays performance sorting

我有一个Entry对象数组(它是创建基本电话目录的解决方案的一部分) - 每个Entry对象包含三个字段(这是电话目录的数据)      public String surname; public String initial; public String number;

最初,当将这些添加到数组时(我知道数组不是电话目录之类的数据结构的一个很好的选择,但它在规范中),在添加每个条目之后,它被排序 - 想法是因为java库排序使用混合Timsort寻找已经排序的数据的运行,它将比将条目插入正确的位置并且直接将新条目插入到已经排序的数据中快得多且简单得多。正确的位置。

排序方法如下

protected void sort() {

    /*
     * Uses comparator because else it fails to sort the null values to the end of the array, and
     * throws null pointer exception instead
     */

    Arrays.sort(this.directory, new Comparator<Entry>() {
        public int compare(Entry entry1, Entry entry2) {
            if (entry1 == null) { // if entries are null will sort to back of
                                // array
                return 1;
            }

            if (entry2 == null) {
                return -1;
            }

            return entry1.surname.compareTo(entry2.surname); //NB this line
        }

    });
}

然而,有人指出,与另一个对象的字段直接交互是坏的风格(这是有道理的!)。所以上面标记的线被替换为 return entry1.surname.compareTo(entry2.surname);

这意味着它使用条目类中的compareTo方法。但是 - 由于某些我不理解的原因 - 这会慢慢减慢它的速度。它可以在一秒内添加3000个条目到超过30秒 - 考虑到下面的compareTo方法,为什么需要这么长时间?

    @Override
public int compareTo(Entry o) {

    if (this.getClass() == null) {
        return -1;
    }

    if (o == null) {
        return 1;
    }

    if (this.surname.equalsIgnoreCase(o.surname)) {
        return this.initial.compareToIgnoreCase(o.initial);
    }

    return this.surname.compareToIgnoreCase(o.surname);

}

1 个答案:

答案 0 :(得分:2)

你的领带解决逻辑是倒置的:不是先比较姓氏的平等,先将它们与compareToIgnoreCase进行比较,然后检查结果为零。否则,您实际上两次进行比较:

int res = this.surname.compareToIgnoreCase(o.surname);
return res != 0 ? res : this.initial.compareToIgnoreCase(o.initial);

假设少数关系,这应该加快你的双重比较。

此外,您的代码还有其他低效率:例如,对this.getClass()的结果进行空检查毫无意义,因为它永远不会null