简体   繁体   中英

how to deep copy one arraylist into another

I am trying some java for first time. I tried creating an arraylist of arraylist and wanted to deep copy one arraylist into another arraylist. When executed the below code I get error:

import java.util.ArrayList;
import java.util.Scanner;
public class MyClass {
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        ArrayList<ArrayList<Integer>> arrli = new ArrayList<ArrayList<Integer>>();
        System.out.println("Enter the array size: ");
        int n = sc.nextInt();
        int arr[] = new int[n];
        System.out.println("Enter "+ n + " elements: ");
        for(int i=0; i<n; i++) {
            arr[i] = sc.nextInt();
        }
        ArrayList<Integer> arrli1 = new ArrayList<Integer>();
        for(int i=0; i<n; i++) {
            if(i==0) {
                arrli1.add(arr[i]);
            } else if(arr[i] > arr[i-1]) {
                arrli1.add(arr[i]);
            } else if(arr[i] < arr[i-1]) {
                arrli.add(arrli1.clone());
                arrli1.clear();
                arrli1.add(arr[i]);
            }
            if(i==(n-1)) {
                arrli.add(arrli1);
            }
        }
        int s = arrli.size();
        int inner_size;
        for(int i=0; i<s; i++) {
            inner_size = arrli.get(i).size();
            for(int j=0; j<inner_size; j++){
                System.out.print(arrli.get(i).get(j));
            }
            System.out.println();
        }
    }
}

Output:

/MyClass.java:21: error: no suitable method found for add(Object)
                arrli.add(arrli1.clone());
                     ^
    method Collection.add(ArrayList<Integer>) is not applicable
      (argument mismatch; Object cannot be converted to ArrayList<Integer>)
    method List.add(ArrayList<Integer>) is not applicable
      (argument mismatch; Object cannot be converted to ArrayList<Integer>)
    method AbstractCollection.add(ArrayList<Integer>) is not applicable
      (argument mismatch; Object cannot be converted to ArrayList<Integer>)
    method AbstractList.add(ArrayList<Integer>) is not applicable
      (argument mismatch; Object cannot be converted to ArrayList<Integer>)
    method ArrayList.add(ArrayList<Integer>) is not applicable
      (argument mismatch; Object cannot be converted to ArrayList<Integer>)
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

What am I missing here. Please shed some light on this.

As I mentioned in my comments to your question, the clone() method returns an Object, and since the compiler can see and know only this, you must (dangerously) cast the object returned to be ArrayList for the method to work:

arrli.add((ArrayList<Integer>) arrli1.clone());

Having said this, I implore you not to use clone() in this situation and that you read Why people are so afraid of using clone() (on collection and JDK classes)? to see why.

If this were my code, I'd make new ArrayLists objects within the for loop rather than cloning existing ones. I'm not 100% sure of what you're trying to achieve here, but perhaps something similar to:

// list to hold other lists
List<List<Integer>> listOfLists = new ArrayList<>();

// inner list to be added to above list
List<Integer> innerList = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {  

    // if we need to create a new inner list, add old to 
    // list of lists and create new one          
    if (i != 0 && arr[i] < arr[i - 1]) {
        listOfLists.add(innerList);
        innerList = new ArrayList<>();
    }

    // always add to the current inner list
    innerList.add(arr[i]);
}

// when all is done, add last inner list to list of lists
listOfLists.add(innerList);

This above code looks to be cleaner and safer. Also, if you're wondering why I'm using:

List<Integer> foo = new ArrayList<>();

rather than

ArrayList<Integer> foo = new ArrayList<>();

Please check out:

Don't use clone() to copy an ArrayList . Use the copy-constructor.

Making a deep copy of an ArrayList<ArrayList<Integer>> is actually very simple:

ArrayList<ArrayList<Integer>> arrli = /*...*/

// Create deep copy (no need to copy immutable Integer objects)
ArrayList<ArrayList<Integer>> copy = new ArrayList<>(arrli.size());
for (ArrayList<Integer> sublist : arrli)
    copy.add(new ArrayList<>(sublist));

The code of course assumes there are no null sublists.

.clone() returns an Object so you must cast it into your proper type. In your case ArrayList<Integer>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM