Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AbstractCollection为什么不实现size()?_Java_Collections_Size - Fatal编程技术网

Java AbstractCollection为什么不实现size()?

Java AbstractCollection为什么不实现size()?,java,collections,size,Java,Collections,Size,当对AbstractCollection进行子分类时,我仍然必须实现size(),即使(我相信)有一个合理正确(尽管没有性能)的默认实现: public int size() { int count = 0; for (Iterator<E> i = iterator(); i.hasNext();) { i.next(); count++ } return count; } public int size(){

当对AbstractCollection进行子分类时,我仍然必须实现
size()
,即使(我相信)有一个合理正确(尽管没有性能)的默认实现:

public int size() {
    int count = 0;

    for (Iterator<E> i = iterator(); i.hasNext();) {
        i.next();
        count++
    }

    return count;
}
public int size(){
整数计数=0;
for(迭代器i=Iterator();i.hasNext();){
i、 next();
计数++
}
返回计数;
}

为什么设计人员没有包含
size()
的默认实现?他们是否试图强迫开发人员有意识地考虑这种方法,希望让开发人员提供一种性能优于默认值的实现?

我怀疑您的最后一句话是真正的原因。当对抽象类进行子类化时,有时只会覆盖抽象方法。我希望几乎每个实现都有一个比迭代更好的实现——因此,如果您希望几乎每个人都重写一个方法,那么最好不要提供基本(缓慢)实现。它只是减少了出错的机会:)

虽然这是一个可能的默认实现,但它不一定是一个好的实现(甚至不是一个正常的实现)

几乎所有的通用
集合
实现中,都有一个O(1)方法来确定大小。通常只需查询一个简单字段


这应该是执行。在极少数情况下,如果不是这样的话,实现仍然可以回到您的示例代码(或者以不同的方式实现)。

我支持您的理论:可能实现者只是被迫为
size()
实现一个好的(
O(1)
,如果可能的话)实现,因为

  • 这种方法经常使用
  • 如果我们针对接口编程,我们不知道实际的集合类型
  • 默认(或错误)实现可能会意外地破坏性能

实际上,由于
add
remove
操作都有一个返回值,指示该操作是否导致集合大小的更改,因此在大多数情况下,通过跟踪添加和删除,您可以更好地实现事件
size
方法

对于某些类型的列表,您建议的默认实现是有害的。我想到的是惰性列表,或者迭代时导致内存中数据结构非常大的列表


在无限延迟列表的情况下,您建议的默认实现显然是不正确的。

例如,对于ArrayList来说,它不是非常合理的实现。这可能就是为什么他们在默认情况下没有实现它以避免隐藏的陷阱。@denis.solonenko:我的意思是,从正确性的角度来看,它是合理的。我同意你的观点,从性能的角度来看这是不合理的。我所知道的没有一种情况,该方法不会被重写。尽管CLQ接近这一点,但impl速度更快。简单地说:这是一段无用的代码,每次都必须重写它,它会抛出ConcurrentModificationException,在这种情况下,你会怎么做?@bestsss:我同意。我几乎总是提供优于O(N)的实现。我只是好奇,看看人们还能想出什么其他理由@亚当,顺便说一句,如果(++count==Integer.MAX_VALUE)返回count,您需要像
一样退出
而不是
count++
实际上迭代可以抛出一个
concurrentModificationException
,这对于
size()
@bestsss()是不可接受的,这是一个运行时异常。。。如果一个集合没有被记录为线程安全的(这是唯一可能出现问题的地方),那么我认为size()抛出ConcurrentModificationException并不可怕。集合框架的所有异常都是运行时异常,但它们都被记录了(包括NPE、ClassCastException、ArrayStoreException等).@bestsss:那么可能应该实际记录
size()
,从而可能引发此问题。为什么不可能有一个需要多个操作来计算大小的集合呢?然后是isEmpty()等等。基本上一切都好。我的理解是size()是在尽最大努力的基础上工作的。