1

I need to write out a method to clone a nested ArrayList.

The nested ArrayList looks like this:

ArrayList<ArrayList<Ship>> theSea = new ArrayList<ArrayList<Ship>>();

I want to copy it to a clone:

ArrayList<ArrayList<Ship>> seaClone = new ArrayList<ArrayList<Ship>>();

I've tried iterating it and copying over the lists:

for(int i = 0; i < theSea.size(); i++){
    seaClone.add(theSea.get(i));
}

However, this doesn't clone the elements of the nested ArrayList<Ship> and instead just copies over a reference to it.

How should I go about cloning the elements of the nested ArrayList<Ship>?

Brian
  • 119
  • 6
  • how does your `Ship` class look like? – Ousmane D. Apr 27 '18 at 19:59
  • You need two loops, one iterating over the outer `List`, one iterating over the inner `List`s. And don't use `clone()` and `Cloneable` [since it is broken](https://www.artima.com/intv/bloch13.html). – Turing85 Apr 27 '18 at 20:01
  • You could override the clone method in you class `Ship` (deep copy). Then write a function to make a deep copy of a ArrayList `for(Ship s : oldList) newLidt.add(s.copy());`. Now you should call this written method for all ArrayList row... – 0x1C1B Apr 27 '18 at 20:05
  • @0x1C1B you could use `clone()`, but you shouldn't. See the link in my previous comment. – Turing85 Apr 27 '18 at 20:06
  • @Brian why not try it out? – Turing85 Apr 27 '18 at 20:06
  • @Turing85 would the code look something like this: `for(int i = 0 ; i –  Brian Apr 27 '18 at 20:08
  • @Brian again... why not try it out? I will not look at code you post in the comments. – Turing85 Apr 27 '18 at 20:09
  • @Turing85 I get the ConcurrentModificationException. I tried splitting up the `for` loop so that I first add the lists to seaClone then add the elements of theSea.get().get(). My issue now lies in how to iterate over theSea without concurrently modifying it? –  Brian Apr 27 '18 at 20:22
  • Do you need to clone `Ship`, or just the nested list? – shmosel Apr 27 '18 at 20:22
  • @shmosel I need to clone every `Ship` element as well –  Brian Apr 27 '18 at 20:23
  • @Brian [Please do your research.](https://stackoverflow.com/questions/3184883/concurrentmodificationexception-for-arraylist) – Turing85 Apr 27 '18 at 20:24

3 Answers3

0

However, this doesn't clone the elements of the nested ArrayList and instead just copies over a reference to it.

Because it is actually what you are doing : you add the reference of the existing objects in the new List.
So instead of, create a new nested ArrayList for each cloned sublist and create new Ship objects as you add elements in the new Lists.
You could define a copy constructor in Ship for example :

public Ship(Ship model){     
  foo = model.foo;
  bar = model.bar;    
}

You can so write :

for(List<Ship> list : theSea){
    List<Ship> currentList = new ArrayList<>();
     for(Ship ship : list){
        currentList.add(new Ship(ship));
     }
    clone.add(currentList);
  }
davidxxx
  • 125,838
  • 23
  • 214
  • 215
0

Assuming Ship objects are cloneable:

List<List<Ship>> clone = theSea.stream()
    .map(l -> l.stream().map(s -> (Ship)s.clone()).collect(toList()))
    .collect(toList());
sprinter
  • 27,148
  • 6
  • 47
  • 78
  • @Turing85 in your (and Bloch's) opinion. It's not mine. There are plenty of situation in which it can be used safely. – sprinter Apr 27 '18 at 20:34
0

Something like:

ArrayList<ArrayList<Ship>> listCopy = new ArrayList<>();
for (int i=0; i<list.size(); i++) {
    ArrayList<Ship> newList = new ArrayList<>();
    for (int j=0; j<list.get(i).size(); j++) {
        newList.add(new Ship(list.get(i).get(j)));
    }
    listCopy.add(newList);
}

Observe this line: newList.add(new Ship(list.get(i).get(j)));

Where you need to pass the object to the constructor and from there duplicate all the attributes, otherwise you will just create a reference to the same class.

If your ship class is to complex with many other objects inside this task may be difficult and you can use a tool like serializing to json and then revert back to object or using a java deep object cloner.

justcode
  • 1,562
  • 3
  • 14
  • 25