如果我知道要创建多少个集合,应该全部创建它们或通过add()即时创建它们

发布于 2025-02-06 02:55:44 字数 384 浏览 0 评论 0原文

我需要创建数百个对象的数组。 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉栀 2025-02-13 02:55:45

如果您检查添加(E E)在类arraylist内的实现,则可以看到以下内容:

public boolean add(E e) {
    modCount++;
    add(e, elementData, size); //check below
    return true;
}

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}

因此,基本上是arraylist.add()的唯一一次做的不仅仅是简单地设置e []所保留的数组,而是s == elementData.length

如果您检查这些字段是什么:

  • elementData:“存储了数组元素的数组缓冲区。阵列列表的容量是此数组缓冲区的长度”
  • size :“ ArrayList的大小(其包含的元素数)。”

因此,如果您检查构造函数public ArrayList(int InitialCapacity),您可以看到,当您提供初始容量时,数组elementData将以您提供的能力初始化:

if (initialCapacity > 0) {
    this.elementData = new Object[initialCapacity];

换句话说,这意味着如果(s == elementData.length)如果您事先知道将存储在数组中的元素的数量,则永远无法满足条件,因此elementData = grow()永远不会被称为使用.add()方法基本上等同于您通过index手动设置数组中的每个元素。

总而言之,如果您知道您将在列表中存储850元素,那么这样做:

List<Element> elements = new ArrayList<>(850);
elements.add(element1);
elements.add(element2);
//...
elements.add(element850);

...实际上是等效的,在操作方面,要比将设置放入数组中(有一个如果检查,一个增加了,但这确实是无关紧要的)。具有优势,尽管您拥有一个结构,例如list,该结构使对象更易于使用(您可以使用迭代器和所有其他功能list提供的所有其他功能界面)。

因此,尤其是当元素的数量如此之小(&lt; 1000)时,并且您知道它们的预先数量时,我不会过度考虑它,而直接进入arraylist

If you check the implementation of add(E e) inside the class ArrayList, you can see this:

public boolean add(E e) {
    modCount++;
    add(e, elementData, size); //check below
    return true;
}

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}

So basically, the only time when ArrayList.add() does something more than simply setting an element inside the E[] array that it holds, is when s == 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 array elementData will be initialized with the capacity you provide:

if (initialCapacity > 0) {
    this.elementData = new Object[initialCapacity];

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 the elementData = 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:

List<Element> elements = new ArrayList<>(850);
elements.add(element1);
elements.add(element2);
//...
elements.add(element850);

... 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 by List 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.

昔梦 2025-02-13 02:55:45

elementData = grow()超级至关重要。 arrayList使用双重和副本策略来摊销插入成本。当它达到内部缓冲区的长度时,它会创建一个与最后一个大小的新数组,并在旧数据中复制。因此,添加(x)摊销到o(1)(contand),因为在足够的添加 s的过程中,它平均为常数插入时间。

我的意思是,从逻辑上考虑这一点:

  1. 如果没有任何后果,为什么在构造函数中提供
  2. 它如何继续接受数据并像数组一样行事?

但是,他是对的:除非您正在使用庞大的列表并永久更新它,否则它没有结果效应

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 to O(1) (constant) because over the course of enough adds, it averages to a constant insertion time.

I mean, think about this logically:

  1. Why on earth offer an initialSize in the constructor if it's of no consequence?
  2. How can it continue to just accept data and behave like an array?

But, he is right: unless you're working with a huge list and perpetually updating it, its of no consequential effect

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文