【问题标题】:How to copy java.util.list Collection如何复制 java.util.list 集合
【发布时间】:2012-05-14 11:39:12
【问题描述】:

我正在实现一个负责订购 java.util.List 的 Java 类。当我使用这个类时,问题就来了。我可以订购列表,但我想复制“原始”列表而不进行修改,以便我可以注册原始列表上所做的每一个更改。排序后的列表包含对象,其中一个字段存储了一个分类 id,这个 id 用列表的索引值更新。

我尝试使用克隆方法,它使列表保持未排序,但对原始列表所做的更改也会在克隆列表中更新。

有什么方法可以实现吗?

我的代码:

List<Torero> listaTorero = tbTlgTorerolHome.findByExample(new Torero());
List<Torero> listaToreroTemp = ((List<Torero>) ((ArrayList<Torero>) listaTorero).clone()); 

Clasificacion clasificacion = new Clasificacion();

Iterator<Torero> iterTorero = clasificacion.getClasificacion(listaTorero, torero).iterator(); //Sorting List

分类方法:

public List<Torero> getClasificacion(List<Torero> listaToreroTemp, Torero torero)
{

    List<Torero> listaTorero = new ArrayList<Torero>();

    Collections.sort(listaToreroTemp,new ToreroClasifiacionComparator());

    Iterator<Torero> iterTorero = listaToreroTemp.iterator();
    int index=1;
    while(iterTorero.hasNext())
    {
        Torero toreroTemp = iterTorero.next();
        toreroTemp.setNumClasificacion(index);
        listaTorero.add(toreroTemp);
        index=index+1;
    }
    return listaTorero;
}

【问题讨论】:

标签: java clone


【解决方案1】:

您可以使用以前列表的输入创建一个新列表,如下所示:

List one = new ArrayList()
//... add data, sort, etc
List two = new ArrayList(one);

这将允许您独立于第一个列表修改顺序或包含哪些元素。

请记住,尽管这两个列表将包含相同的对象,因此如果您修改列表 2 中的一个对象,则列表 1 中将修改相同的对象。

示例:

MyObject value1 = one.get(0);
MyObject value2 = two.get(0);
value1 == value2 //true
value1.setName("hello");
value2.getName(); //returns "hello"

编辑

为避免这种情况,您需要对列表中的每个元素进行深层复制,如下所示:

List<Torero> one = new ArrayList<Torero>();
//add elements

List<Torero> two = new Arraylist<Torero>();
for(Torero t : one){
    Torero copy = deepCopy(t);
    two.add(copy);
}

复制如下:

public Torero deepCopy(Torero input){
    Torero copy = new Torero();
    copy.setValue(input.getValue());//.. copy primitives, deep copy objects again

    return copy;
}

【讨论】:

  • 但这是我想要避免的,例如,如果我在列表二上更改 value2,我不想在列表一上传播此更改。
  • 啊,这改变了事情,你有一个方法或构造函数可以将一个 Torero 复制到另一个?
  • 不,我没有,你能给我一点线索吗?
  • 这是可行的,但我避免手动设置对象的每个元素。我知道还有其他选择...谢谢。
  • 如果您想要一个库来为您完成这项工作,请查看 Apache Commons BeanUtils.cloneBean()。这使用反射将属性从一个对象复制到另一个对象。 commons.apache.org/beanutils/api/org/apache/commons/beanutils/…
【解决方案2】:

使用 ArrayList 复制构造函数,然后对其进行排序。

List oldList;
List newList = new ArrayList(oldList);
Collections.sort(newList);

复制后,对 newList 的任何更改都不会影响 oldList。

但是请注意,只有 references 被复制,因此两个列表共享相同的对象,因此对一个列表的 elements 所做的更改会影响 elements 另一个。

【讨论】:

  • 是否有任何方法不会传播对复制列表元素所做的更改?
  • 它在技术上不是传播,因为您对同一个对象有多个引用。您要么必须制作副本(这会降低时间和空间效率),要么使用不可变对象(或可变对象周围的不可变包装器)。
猜你喜欢
  • 2012-12-28
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 2016-02-27
  • 2020-02-13
相关资源
最近更新 更多