【问题标题】:ArrayList or several for loops?ArrayList 还是几个 for 循环?
【发布时间】:2013-10-24 13:47:42
【问题描述】:

我知道这可能很简单,我有一种情况需要在使用四个 for 循环(两个用于计数和删除空元素,两个用于添加元素)合并两个字符串数组或使用两个 for 循环之间做出决定使用 ArrayList 并使用 ArrayList.toArray() 将 ArrayList 转换为数组。

这两种方法在性能方面有什么不同吗?

编辑

由于兼容性问题,我不得不放弃使用泛型方法的 ArrayList。但这里是较早的代码。

List<String> newList = new ArrayList<String>();

    for (String element : array1)
    {
      if (element != null)
      {
        newList.add(element);
      }
    }

    for (String element : array2)
    {
      if (element != null)
      {
        newList.add(element);
      }
    }

    return newList.toArray(new String[]{});

我用一个循环编写了一个新代码,但我想我可能会在精神上杀死下一个阅读此代码的人。

String[] newArr = new String[array1.length + array2.length];
int n = 0;

for (int i = 0; i < newArr.length; i++)
{
  if (i < array1.length && array1[i] != null)
  {
    newArr[n] = array1[i];
    n++;
  }

  if (i >= array1.length)
  {
    int a = 0;
    if (array1.length < array2.length)
    {
      a = (i - array1.length) + (array2.length - array1.length);
    }
    else
    {
      a = i - array1.length;
    }

    if (array2[a] != null)
    {
      newArr[n] = array2[a];
      n++;
    }
  }
}

return newArr;

终于知道不需要空元素检查,所以继续使用这个简单的代码。

String[] newArr = new String[array1.length + array2.length];

    System.arraycopy(array1, 0, newArr, 0, array1.length);
    System.arraycopy(array2, 0, newArr, array1.length, array2.length);

    return newArr;

从下面的讨论中我猜想第二种方法性能更好。

【问题讨论】:

  • 你能粘贴你的代码吗?
  • 您可能需要考虑使用 LinkedList,除非您事先知道数组的大小。
  • @SimonAndréForsberg 是的,但这并不是那么糟糕。将项目添加到 ArrayList 仍然是 O(1) 摊销时间,更重要的是,它在实践中很快。在实践中,我几乎从未发现 LinkedList 更快,尤其是在这种情况下,您只追加到末尾然后迭代项目。因此,请务必尝试以确保它确实是一种改进。
  • @Chamilla:所以,你不愿意对自己的代码进行基准测试,你认为我们会为你做这件事吗?
  • 这个问题似乎是题外话,因为它是关于众包基准测试工作。这个问题太本地化了,对任何人都没有多大用处。

标签: java performance for-loop arraylist


【解决方案1】:

假设 1 个 for 循环的时间复杂度为 O(n),则 4 个 for 循环和 2 个 for 循环的时间复杂度相同

4*O(n) = O(n)
2*O(n) = O(n)

但是使用数组而不是 ArrayList 会占用更少的内存。所以选择第一种。

【讨论】:

  • would take the same time 这是用词不当。他们绝对不会花费相同的时间。它们只是属于同一个时间复杂度类。两种截然不同的东西。
  • 它们确实需要不同的时间,但是当我们谈论大数据时,我们确实倾向于忽略这些差异。对吗?
  • @AnkitRustagi 在理论计算机科学中,算法采用“两倍于另一个”的算法或多或少是无关紧要的。我们只特别关心算法随着 n 的增加而增长的速率。话虽这么说,在现实世界的应用中,2 倍是巨大的,尤其是当较短的那个已经是人类可察觉的时间量时。
  • 当我们谈论更大的数据时,我们谈论的是更大的差异。
  • 所以一件事需要一天还是两天没有区别?
【解决方案2】:

尽量避免循环,因为每次使用n 元素循环时,时间和空间复杂度都会增加n

请粘贴您的代码。

【讨论】:

  • for(int i = 0 ; i &lt; n ; i++){for(int j = 0 ; j &lt; n ; j++){for(int k = 0 ; k &lt; n ; k++){}}} 的空间复杂度为 O(1)。
【解决方案3】:

与第二个选项一样,将保存对集合的 2 次迭代,如果列表中的对象数量很高,这肯定会提高性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-10
    • 2013-08-07
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2016-06-20
    • 1970-01-01
    • 2021-02-13
    相关资源
    最近更新 更多