如果我知道要创建多少个集合,应该全部创建它们或通过add()即时创建它们
我需要创建数百个对象的数组。 myObject
具有较大的内存足迹,一次创建的精力/时间需要一定的时间和时间。我知道我开始有多少。我可以适当地创建一个数组myObject [n]
大小,然后通过索引插入myObject
。或者我可以创建arrayList< myObject>
然后进行add(myObject)
。代码大小和结构相似,但我可以想象第二种方法“可以”与第一个方法不同。 (真的吗?)我想区别很小,尤其是考虑到少于1000个条目,但是我猜测,第一种方法是更好的,因为它使用了我较早的过程中的信息。 arraylist.add()
是否必须做额外的工作以增加其大小?
I need to create an array of several hundred objects. MyObject
has a large memory footprint, takes as bit of effort/time to create and will be created one at a time. I know how many when I start. I can create an array MyObject[n]
sized appropriately then insert the MyObject
via an index. Or I can create an ArrayList<MyObject>
then do an add(MyObject)
. The code size and structure is similar but I can imagine the second method 'could' fragment the memory differently than the first method. (Really?) I suppose the difference is pretty small, especially considering there are less than 1000 entries, but my guess is that the first method is better as it uses information I have earlier in the process. Does the ArrayList.add()
have to do extra work to increase its size?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您检查
添加(E E)
在类arraylist
内的实现,则可以看到以下内容:因此,基本上是
arraylist.add()的唯一一次
做的不仅仅是简单地设置e []
所保留的数组,而是s == elementData.length
。如果您检查这些字段是什么:
elementData
:“存储了数组元素的数组缓冲区。阵列列表的容量是此数组缓冲区的长度”size :“ ArrayList的大小(其包含的元素数)。”
因此,如果您检查构造函数
public ArrayList(int InitialCapacity)
,您可以看到,当您提供初始容量时,数组elementData
将以您提供的能力初始化:换句话说,这意味着
如果(s == elementData.length)
如果您事先知道将存储在数组中的元素的数量,则永远无法满足条件,因此elementData = grow()
永远不会被称为使用.add()
方法基本上等同于您通过index手动设置数组中的每个元素。总而言之,如果您知道您将在列表中存储
850
元素,那么这样做:...实际上是等效的,在操作方面,要比将设置放入数组中(有一个如果检查,一个增加了,但这确实是无关紧要的)。具有优势,尽管您拥有一个结构,例如
list
,该结构使对象更易于使用(您可以使用迭代器和所有其他功能list
提供的所有其他功能界面)。因此,尤其是当元素的数量如此之小(&lt; 1000)时,并且您知道它们的预先数量时,我不会过度考虑它,而直接进入
arraylist
。If you check the implementation of
add(E e)
inside the classArrayList
, you can see this:So basically, the only time when
ArrayList.add()
does something more than simply setting an element inside theE[]
array that it holds, is whens == elementData.length
.If you check what these fields are:
elementData
: "The array buffer into which the elements of the ArrayList are stored. The capacity of the ArrayList is the length of this array buffer"size
: "The size of the ArrayList (the number of elements it contains)."So, if you check the constructor
public ArrayList(int initialCapacity)
, you can see that when you provide an initial capacity, the arrayelementData
will be initialized with the capacity you provide:Which, in other words, means that the
if (s == elementData.length)
condition will never be met if you know in advance the number of elements that you will store in the array, and so theelementData = grow()
will never be called making the usage of.add()
method basically equivalent to you manually setting each element inside the array by index.To sum up, if you know that you will store
850
elements in your list, then doing this:... is practically equivalent, operations-wise, than doing the set into an array yourself (there is one if-check and one increment more but that's really irrelevant). With the advantage though that you have a structure such as
List
that makes the object much easier to use (you'll be able to use iterators and all other features provided byList
interface).So especially when the number of elements is so small (< 1000) and that you know how many they are in advance, I wouldn't overthink it and go directly into an
ArrayList
.elementData = grow()
超级至关重要。arrayList
使用双重和副本策略来摊销插入成本。当它达到内部缓冲区的长度时,它会创建一个与最后一个大小的新数组,并在旧数据中复制。因此,添加(x)
摊销到o(1)
(contand),因为在足够的添加
s的过程中,它平均为常数插入时间。我的意思是,从逻辑上考虑这一点:
?
但是,他是对的:除非您正在使用庞大的列表并永久更新它,否则它没有结果效应
elementData = grow()
is super crucial.ArrayList
uses the double-and-copy strategy to amortize the cost of insertion. When it hit's the length of it's internal buffer it creates a new array of double the size of the last and copies in the old data. So,add(x)
amortizes toO(1)
(constant) because over the course of enoughadd
s, it averages to a constant insertion time.I mean, think about this logically:
initialSize
in the constructor if it's of no consequence?But, he is right: unless you're working with a huge list and perpetually updating it, its of no consequential effect