【问题标题】:What is the time complexity to copy one arraylist to another in Java?在 Java 中将一个数组列表复制到另一个数组的时间复杂度是多少?
【发布时间】:2018-11-23 20:09:49
【问题描述】:
ArrayList<Integer>arr1=new ArrayList<Integer>();
 arr1.add(1);
 arr1.add(2);
 arr1.add(3);
ArrayList<Integer>copyArray=new ArrayList<Integer>(arr1);

上面的代码是否将一个 arrayList 复制到另一个 arrayList 工作在 O(1) 或深入它是 O(n) ,似乎将一个数组的每个元素复制到另一个它会一个一个地迭代,这会导致在 O(n) 中,还是只是对对象池的引用?

【问题讨论】:

  • 'Deep down' System.arraycopy(...) 被使用,导致 O(n)。

标签: java arraylist


【解决方案1】:

查看源码,ArrayList(Collection&lt;? extends E&gt; c)构造函数内部调用c.to Array()

toArray() 的 Java 文档 https://docs.oracle.com/javase/9/docs/api/java/util/ArrayList.html#toArray--

表示它对源数组进行了深层复制并返回安全复制的数组。因此,客户端对重新调整的数组所做的任何更改都不会影响 ArrayList 的内部数据结构。所以在最坏的情况下它的 O(n)。

【讨论】:

    【解决方案2】:

    寻找源头:

    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    }
    

    ArrayList(Collection) 构造函数调用toArray(),后者调用Arrays.copyOf

    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }
    

    这里重要的部分是System.arraycopy,这是一个本地调用。 Another question on SO 解决了这个调用的时间复杂度,结论似乎是这个调用在最坏的情况下是 O(n),但是某些系统可能对某些数据类型使用块副本(如我想象的原语),从而导致运行时比 for 循环迭代更高效。

    【讨论】:

      【解决方案3】:

      在内部它使用 Arrays.copyOf 进一步使用复杂度为 O(n) 的 System.arraycopy。查看以下来源:

      public ArrayList(Collection<? extends E> c) {
          elementData = c.toArray();
          if ((size = elementData.length) != 0) {
              // c.toArray might (incorrectly) not return Object[] (see 6260652)
              if (elementData.getClass() != Object[].class)
                  elementData = Arrays.copyOf(elementData, size, Object[].class);
          } else {
              // replace with empty array.
              this.elementData = EMPTY_ELEMENTDATA;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-23
        相关资源
        最近更新 更多