如何在Java中创建ArrayList <integer>的深层副本?

时间:2017-02-06 11:49:30

标签: java arraylist deep-copy

我基本上只是想制作一个零和一个零的深层副本,所以我可以使用布尔值,但我想知道如何在整数的genereal中做到这一点。

private ArrayList<Integer> makeDeepCopyInteger(ArrayList<Integer> a) {
    ArrayList<Integer> newA = new ArrayList<>(a.size());
    for (int i = 0; i < a.size(); i++) {
        int newInt = 0;
        if (a.get(i) == 1) {
            newInt = 1;
        }
        newA.add(newInt);
    }
    return newA;
}

4 个答案:

答案 0 :(得分:1)

clone()方法受Integer类保护,因此您无法在该类之外调用Integer.clone()。你可以做的是创建一个new整数。

private ArrayList<Integer> makeDeepCopyInteger(ArrayList<Integer> old){
    ArrayList<Integer> copy = new ArrayList<Integer>(old.size());
    for(Integer i : old){
        copy.add(new Integer(i));
    }
    return copy;
}

您可以通过执行以下操作来测试此功能:

public static void main (String[] args) throws java.lang.Exception
{
    ArrayList<Integer> arr = new ArrayList<>();
    for(int i = 0; i<5; i++){
        arr.add(new Integer(i));
    }
    ArrayList<Integer> x = makeDeepCopyInteger(arr);
    for(int i = 0; i<x.size(); i++){
        if(arr.get(i) == x.get(i)){
            System.out.println("Same object");
        } else {
            System.out.println("Not the same object");
        }
    }
}

测试

Integer a = new Integer(1);
Integer b = new Integer(a);

System.out.println(a==b); // true
System.out.println(System.identityHashCode(a) == (System.identityHashCode(b))); // false;


Integer a = new Integer(1);
Integer b = a;

System.out.println(a==b); // true
System.out.println(System.identityHashCode(a) == (System.identityHashCode(b))); // true

因此,在我的测试中,似乎要创建一个新的引用以复制到新数组,您应该使用new Integer()Integer是一个不可变对象,但当Integer的值发生变化时,该引用会发生变化。

答案 1 :(得分:1)

使用流来复制对象。易于阅读,适合JIT。下面的代码提供了一个包含Integer对象副本的列表的副本。

private ArrayList<Integer> makeDeepCopyInteger(ArrayList<Integer> a){
    return a.stream().map(val -> new Integer(val)).collect(toList());
}

复制除Integer覆盖工具以外的自定义对象并调用clone()

return a.stream().map(MyObjectClass::clone).collect(toList());

您可以将序列化用于json,而不是克隆。例如。在以下java-utils

中的BeanUtils.getCopy(sourceBean)中使用

答案 2 :(得分:0)

你必须迭代列表中的项目并克隆它们,然后将它们添加到新列表中,如下所述:

How to clone ArrayList and also clone its contents?

答案 3 :(得分:0)

可以做类似的事情:

        <div id="contact">
		<p onmouseover="opentabs()" onmouseout="closetabs()" style="text-align: center;">Home</p>
		</div>
		<div id="about">
		<p style="text-align: center;">About</p>
		</div>
		<div id="location">
		<p style="text-align: center;">Location</p>
		</div>

或者,更老套:

public static List<Integer> clone(List<Integer> source) {
   return source.stream()
       .map( intObj -> new Integer(intObj.intValue()))
       .collect(Collectors.toList());
}

利用自动装箱/自动拆箱功能,可以缩短这些功能。但我明确表示要清楚地知道发生了什么。

然而,这是一项毫无意义的练习 - 实际上它会积极地浪费记忆并且不利于表现。 public static List<Integer> clone(List<Integer> source) { List<Integer> newList = new ArrayList<>(); for(Integer intObj : source) { newList.add(new Integer(intObj.intValue())); } return newList; } 是不可变的,因此对于指向同一Integer实例的引用,更好。因为Integer无法更改值,所以不可能通过共享实例来造成任何伤害。

这对于一般的不可变对象都适用,这也是它们是好事的原因。

作为初学者,你不太可能找到一个Integer是个好主意的案例(甚至是new Integer(...),尽管这个案例可能会返回一个缓存的实例)。如果您已经拥有Integer.valueOf(int i),请使用您拥有的那个:

Integer

不变性意味着永远都是好的。 Integer oldVar = ... ; Integer newVar = oldVar; 上的操作无法破坏newVar,因为没有oldVar

如果您有newVar.setValue(newValue)直接使用它并允许Java的自动装箱将其转换为int

Integer

你提到你真的想和布尔人一起工作。您应该考虑使用 int oldValue = ... ; Integer newValue = oldValue ; // Java will automatically put this through // Integer.valueOf(int i)