【发布时间】:2014-04-29 08:25:43
【问题描述】:
我有一个 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);
}
【问题讨论】:
-
您使用
ignoreCase方法之一,为什么要测试相等性?另外,null元素?首先尝试避免这种情况 -
如果两个参数都是
null会发生什么?在这种情况下,它们应该相等。 -
删除
if (this.getClass() == null){...}。它总是错误的。 -
另外,您将姓氏比较两次。致电
this.surname.compareToIgnoreCase并保存结果。如果为零,则它们相等。 -
@LouisWasserman 我不确定哪种方法也会阻止您的引用 - 如果它是比较器,那么如果它们都是空的,那么如果它们的排名相等或放置一个,实际上并没有任何区别在另一个之上。它不应该影响其他任何东西,因为比较器在排序方法完成后被丢弃。如果你在谈论 compareTo()..well..如果它们都是 null 那么它会在能够运行 compareTo 方法之前抛出 NullPointerException
标签: java arrays performance sorting