【问题标题】:Copying an ArrayList复制 ArrayList
【发布时间】:2013-11-07 13:55:08
【问题描述】:

我有一个通用对象类型的 ArrayList,即列表队列。我想编写一个函数 EnqueueModified,它以一个数组列表和一个列表对象作为输入,并返回另一个 ArrayList,其中包含旧数组列表和列表对象的元素,但不影响传递的原始数组列表。即应在 arraylist 的新副本上执行入队操作并返回。

这可以按如下方式完成:

    public List<E> EnqueueModified(E e, List<E> queue) {
    List<E> clone = new ArrayList<E>(queue);
    clone.add(e);
    return clone;

}

但是有没有更好的方法来做到这一点?有没有更快的方法来创建列表的副本,而不是使用复制构造函数?我不能使用克隆,因为它不支持通用列表。

【问题讨论】:

  • clone 是最快的方法,它可能对更大的列表产生真正的影响。您可以将未经检查的强制转换为所需的泛型类型。
  • 但是请注意,clone 会逐字节复制,因此如果原版恰好过大(剩余空间很大),则克隆版将完全这方面是一样的,不像从拷贝构造函数获取的实例。
  • @MarkoTopolnik 我只应该为泛型类型编写此函数,因此不能使用未经检查的强制转换。
  • 没有什么能阻止你使用未经检查的强制转换,对于clone,它是 100% 安全的。基本上,这只是解决 Java 泛型模型的无能问题。

标签: java arraylist copy-constructor


【解决方案1】:

要复制列表,您必须创建一个新列表并用旧列表中的项目填充它。

不过,您使用的构造函数实际上可能不是最佳选择。如果您检查源代码(google arraylist 源代码),您会注意到它创建的数组与旧集合中的元素一样大。

然后它将一个元素添加到该数组中。因为数组太小,它必须创建数组的另一个副本,只是稍微大一点,然后再将元素移动到那里。

你可以通过使用获得更好的性能

clone = new ArrayList(queue.size() + 1);
clone.addAll(queue);
clone.add(e);

此外,方法名称应以小写字母开头。所以使用: enqueueModified(...)

【讨论】:

    猜你喜欢
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2013-05-09
    • 2015-12-07
    • 1970-01-01
    • 2016-01-13
    相关资源
    最近更新 更多