什么是矢量容量的目的

Vector API定义了4种不同的构造函数:

Vector() Vector(Collection c) Vector(int initialCapacity) Vector(int initialCapacity, int capacityIncrement) 

但它们如何运作以及它们用于什么? 我为什么要为矢量定义固定容量? 即使我将初始容量设置为100,我也可以向向量添加101.项:

 Vector test = new Vector(100); for (int i = 0; i < 100; i++) { test.add(new Object()); } test.add(new Object()); System.out.println(test.size()); System.out.println(test.capacity()); 

在上面的代码中,第二个sysout(test.capacity())写入200.为什么此向量中的容量为200? 初始容量为100,我没有定义容量增量。

我真的想知道是否有使用这些建筑师的真实世界的例子?

还有一个熟悉的问题:究竟是Vector.get(int position)和Vector.elementAt(int position)之间的区别? 我读到在将Vector添加到Collection类之前定义了get方法,因此有必要在以后添加方法elementAt(int position)。 真的吗? 或者还有其他差异吗?

什么是“初始”容量?

初始容量就是: Vector在施工时的容量。

Vector是一种动态可扩展的数据结构,它会根据需要重新分配其后备arrays。 因此,没有最终容量,但您可以设置其初始值。

这是Vector API的摘录:

每个向量都试图通过维持capacitycapacityIncrement来优化存储管理。 capacity始终至少与矢量size一样大; 它通常更大,因为随着组件被添加到向量中,向量的存储以块的大小增加capacityIncrement的大小。 应用程序可以在插入大量组件之前增加向量的capacity ; 这减少了增量重新分配的数量。

注意构建后,也可以使用ensureCapacity来达到同样的效果。

也可以看看

  • 创建集合对象(List,Set等)时,通常会使用称为“initialCapacity”的参数。 这个参数意味着什么,它是如何使用的?

为什么这有关系?

例如,假设您有100个要插入Vector元素。 Nullary构造函数将Vector设置为初始容量为10,并且在生长时将其大小增加一倍。 这意味着要容纳100个元素,在它可以容纳所有100个元素之前,它将加倍到20,40,80,然后最终加倍160。

请注意,执行了4个增量重新分配步骤,当它最终适合所有100个元素时,仅使用60%的实际容量。 另一方面,在插入之前使用ensureCapacity(100) (或使用适当的构造函数重载来实现相同的效果)将使该过程更有效,因为没有多余的未使用容量,并且该arrays只需要重新分配一次。

请注意, 渐近地,上述两个过程同样是最优的O(N)时间和O(N)空间),但当然后者在空间和时间上都是对前者的恒定时间改进。

当然,如果你设置了ensureCapacity(10000000) ,并且只插入了100个元素,你只能使用.001%的容量 – 真是浪费! 因此,如果您提前知道要插入多少元素,则可以通过使用ensureCapacity使过程更有效(通过常数因子),但无论如何,即使没有您的Vector仍可以自己完成一项很好的工作。救命。

也可以看看

  • Java Set初始容量最佳实践

为什么加倍?

没有详细说明,这种增长倍增是几何扩展的一种forms,这使得Vector每次操作能够进行恒定时间摊销分析。 值得注意的是,由数组支持的类似可扩展数据结构ArrayList甚至没有指定其增长策略的细节,但OpenJDK版本的增长因子为3/2

请注意, Vector实际上允许您使用capacityIncrement设置非几何增长因子。 重要的是要意识到如果你将 capacityIncrement 设置 为一个小的非零值,你实际上可以使 Vector 执行可怕的渐进式 。 例如,如果将其设置为1 ,则添加N元素将是O(N^2)操作!

ArrayList不允许您自定义其增长策略,因为您甚至不应该知道(也不关心,真的!)。

也可以看看

  • 维基百科:动态数组
    • 请参阅: 几何扩展和摊销成本

那么elementAtget什么?

直接来自文档 :

从Java 2平台v1.2开始,这个类被改进以实现List接口,使其成为Java Collections Framework的成员。 与新的集合实现不同, Vectorsynchronized

public E elementAt(int index) :返回指定索引处的组件。 此方法的function与get(int)方法(它是List接口的一部分)相同。

所以按时间顺序, Vector有了elementAt ,在它被改装以实现List ,因此必须实现get

请注意有关Vector正在synchronized的部分。 如果您不需要此function, ArrayList将是一个更好的选择,因为您不需要支付线程安全的成本。

也可以看看

  • 如果线程安全性不是问题,则使用Java中的ArrayList与Vectors

如果指定零容量或负容量增量,则每次都会将向量的容量加倍,具体取决于capacityIncrement字段的文档:

当矢量大小超过其容量时,矢量容量自动递增的量。 如果容量增量小于或等于零,则每次需要增长时,矢量的容量加倍。

如果仅指定容量,则默认的capacityIncrement为零 – 因此是倍增行为。

如果您已经很好地了解了集合需要多大的数量,那么您可以指定容量 – 这可以避免不必要的复制。

至于getelementAt() – 是的,为通用集合API添加了elementAt() 。 查看实现,除了错误情况中抛出的exception的精确细节之外,它们是相同的。