Java AbstractList::equals()的JDK实现不会首先检查列表大小是否相等

Java AbstractList::equals()的JDK实现不会首先检查列表大小是否相等,java,list,collections,jdk1.6,Java,List,Collections,Jdk1.6,奇怪的是,AbstractList::equals()的默认JDK 6实现似乎没有首先检查两个列表的大小是否相同: public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof List)) return false; ListIterator<E> e1 = listIterator(); ListIterator e2

奇怪的是,
AbstractList::equals()
的默认JDK 6实现似乎没有首先检查两个列表的大小是否相同:

public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;
    ListIterator<E> e1 = listIterator();
    ListIterator e2 = ((List) o).listIterator();
    while(e1.hasNext() && e2.hasNext()) {
        E o1 = e1.next();
        Object o2 = e2.next();
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }
    return !(e1.hasNext() || e2.hasNext());
}
公共布尔等于(对象o){
如果(o==这个)
返回true;
如果(!(列表实例))
返回false;
ListIterator e1=ListIterator();
ListIterator e2=((List)o).ListIterator();
而(e1.hasNext()&&e2.hasNext()){
eo1=e1.next();
对象o2=e2.next();
如果(!(o1==null?o2==null:o1.equals(o2)))
返回false;
}
返回!(e1.hasNext()| e2.hasNext());
}
如果两个列表都包含大量的项目,或者需要花时间比较的项目,它将在意识到一个列表比另一个列表短之前对它们进行比较;在我看来,这似乎真的很低效,因为这种平等甚至不需要进行一次比较就可以实现

尤其是在很多情况下,列表的大小往往会有所不同。此外,大多数Java
List
实现都有O(1)
size()
性能(甚至LinkedList,它将大小保留在缓存中)

这种默认实现是否有充分的理由

equals方法的操作有一些详细的说明,并且 需要O(n)行为。虽然这可能是次优的 size方法为O(1)的子类,对于某些子类,size 方法本身可能是O(n),请求的行为实际上是 退化。在任何情况下,规范都是明确的,不能进行此更改 被制造出来

注意,如果需要,子类可以重写equals,插入一个大小 适当时进行比较


因此,如果理解得好,它的效率很低,因为它已经被记录下来了?:)@Laurent不是因为“它已经被记录下来了”,而是因为设计决策,原因是“对于某些子类,size方法本身可能是O(n),请求的行为实际上是降级的”:)我理解,但首先所有实现的性能都会降级,因为“其中一些”对我来说,可能慢一点似乎不是一个好决定。我会为O(1)个大小的列表创建一个优化的equals,而为其余的列表创建一个未优化的equals。特别是对于Java中的主力军ArrayList…@Laurent,从长远来看,您可以随时重写并保持一致性<代码>列表::size()性能目前在第一位是不一致的:O(n)或O(1),因此我看不出在不同的列表实现之间尝试使equals()一致的真正意义。。。另一种选择是假设甚至要求size()具有O(1)性能(这是所有主要默认实现的情况),并始终优化equals()。