【问题标题】:Intermediate between LinkedList and ArrayListLinkedList 和 ArrayList 之间的中间体
【发布时间】:2019-01-28 05:06:28
【问题描述】:

在下面的代码中,我有一个查询的结果,但我不知道记录的总数。我必须将它存储在一个容器中。当我读取容器的每条记录时,这将是一个简单的循环,因此不会使用基于索引的访问。

  List<MyObject> list;

  while ( source.hasNext() ) {
      MyObject ob = new MyObject();
      convertObject(ob, source.next());
      list.add(ob);
  }

  ...

  //Another method

  for (MyObject ob : objects){
    showThings(ob);
  }

LinkedList 很差,因为它创建了许多带有指向下一个对象的指针的小对象。它使用更多的内存,使内存更加碎片化并且有更多的缓存未命中。

ArrayList 很差,因为我不知道要插入的记录数。每当我插入一个新项目并且内部数组已满时,它会分配一个更大的内存块并将所有内容复制到新块中。

我在 java.util 中没有找到任何解决方案。所以我考虑写一个自定义列表。它就像一个 LinkedList,但每个单元格都是一个数组。换句话说,第一个节点就像一个 ArrayList,但是当它已满并且我插入一个新对象时,它将创建另一个带有数组的节点来插入新项目,而不是复制所有内容。但是,我可能会以某种方式重新发明轮子。

【问题讨论】:

  • 您对 ArrayList 的具体问题是什么?表现?内存?
  • ArrayList 在空间不足时会产生移动记录的开销。
  • GlueList,我不知道存在,是解决方案。谢谢,这就是答案。
  • 解决方案是什么? ArrayList 有什么问题?

标签: java performance data-structures containers


【解决方案1】:

每当我插入一个新项目并且内部数组已满时,它都会分配一个更大的内存块并将所有内容复制到新块中

这不是真的,你可以预先分配一个你想要的任何大小的哈希数组,并且它只会在空间用完时增加,每次增加 50%,所以如果你对预期大小有合理的猜测,甚至猜测一个很大的数字,重新分配成本将为零或最小。

【讨论】:

  • 每次加倍是否正确?我看到了较早的实现,其中增加的大小不是乘以 2 ......只是要求我更好地理解。泰。
  • @zlakad 你是对的。它通常是大小的 1.5 倍。
  • 它曾经是双倍的,但自从我上次查看源代码以来它发生了变化。
  • @JimGarrison 谢谢。 (顺便说一句,我没有投反对票)。现在我正在查看ArrayList 的源代码。而且,有些东西我不喜欢......
【解决方案2】:

一些谷歌搜索揭开了Brownies Collections' GapList的面纱。 它以块的形式组织其内容,并通过将它们排列在树中来管理它们。如果元素删除后它们变得稀疏,它也会阻止合并。

【讨论】:

  • 我添加了一些信息来展示这个特定实现的相关性。我应该在回答中改进的其他方面?
猜你喜欢
  • 2012-05-26
  • 2012-07-24
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
  • 2013-10-17
相关资源
最近更新 更多