【问题标题】:Fastest way to get the first n elements of a List into an Array将列表的前 n 个元素放入数组的最快方法
【发布时间】:2015-07-09 23:58:59
【问题描述】:

将列表的前 n 个元素存储在数组中的最快方法是什么?

考虑到这个场景:

int n = 10;
ArrayList<String> in = new ArrayList<>();
for(int i = 0; i < (n+10); i++)
  in.add("foobar");

选项 1:

String[] out = new String[n];
for(int i = 0; i< n; i++)
    out[i]=in.get(i);

选项 2:

String[] out = (String[]) (in.subList(0, n)).toArray();

选项 3: 有更快的方法吗?也许使用 Java8 流?

【问题讨论】:

  • 我预计它会因平台和 JVM 而异,您应该尝试自己进行基准测试。
  • 为什么要依赖jvm?如何计算复杂度?
  • 复杂性很简单。这是O(n)。实际表现各不相同。
  • 如果你查看subListtoArray的源代码,两者基本上都在做同样的事情

标签: java arrays performance


【解决方案1】:

假设:

列表 - 列表&lt;String&gt;

使用 Java 8 流,

  • 将列表中的前 N ​​个元素放入列表中,

    List&lt;String&gt; firstNElementsList = list.stream().limit(n).collect(Collectors.toList());

  • 将列表中的前 N ​​个元素放入数组中,

    String[] firstNElementsArray = list.stream().limit(n).collect(Collectors.toList()).toArray(new String[n]);

【讨论】:

  • 为什么这应该比#1更快?
  • 如果我只有 1 个元素,并且我使用上面的流式方式,我会得到 1 个元素和 null
  • @jagamot 如果 N 小于数组大小,请改用 toArray(String[]::new)
  • .limit(n).toList() 工作得很好。
【解决方案2】:

选项 1 比选项 2 快

因为选项 2 创建了一个新的 List 引用,然后从 List 创建了一个 n 元素数组(选项 1 完美地调整了输出数组的大小)。但是,首先您需要修复一个错误。使用&lt;(不是&lt;=)。喜欢,

String[] out = new String[n];
for(int i = 0; i < n; i++) {
    out[i] = in.get(i);
}

【讨论】:

  • 令人惊讶的是,subList 不会复制。它是现有列表中的一个视图。
  • @njzk2 除非该视图是空操作,否则我希望选项 1 更快。
  • 创建视图基本上是创建一个带有一些变量的对象。没有循环,没有复制,真的不多。
  • toArray 更复杂一些。
  • 并且更安全,通过实际的绑定检查(例如如果n &gt;= in.size(),或者如果有人同时更改了列表)。
【解决方案3】:

这主要取决于n 的大小。

如果n==0,没有什么比选项#1 更好:)

如果 n 很大,toArray(new String[n]) 会更快。

【讨论】:

  • 范围 n 约为 1-5,其中 in-List 的大小约为大小的两倍
  • 那么非常确定选项#1。
【解决方案4】:

选项 3

迭代器比使用get 操作更快,因为get 操作必须从头开始,如果它必须进行一些遍历。它可能不会对 ArrayList 产生影响,但其他数据结构可能会看到明显的速度差异。这也与非列表的事物兼容,例如集合。

String[] out = new String[n];
Iterator<String> iterator = in.iterator();
for (int i = 0; i < n && iterator.hasNext(); i++)
    out[i] = iterator.next();

【讨论】:

    【解决方案5】:

    使用: Arrays.copyOf(yourArray,n);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-11
      • 1970-01-01
      • 2023-03-13
      • 2012-05-07
      • 1970-01-01
      • 2018-12-05
      • 1970-01-01
      • 2016-04-04
      相关资源
      最近更新 更多