1
List<List<Integer>> result = new ArrayList<List<Integer>>();
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(5);temp.add(6);
result.add(temp);
temp.clear();

I wrote codes like something above, what puzzles me is when I debug the code, I found the result contains size of 1 but the values (5,6,...) are lost after I applying the clear function, can any one explain why?

i3wangyi
  • 2,279
  • 3
  • 15
  • 12

3 Answers3

5

You have list of lists. After this code

List<List<Integer>> result = new ArrayList<List<Integer>>();
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(5);temp.add(6);
result.add(temp);

situation looks like this

                     ┌───> 5
result ─────> tmp ───┤
                     └───> 6
  • result list contains one element which is tmp list
  • tmp list contains two elements 5 and 6

after

temp.clear();

situation changes to

           // ↓↓↓ `temp.clear()` affects only this list
result ─────> tmp 

so now

  • tmp list is empty
  • but result still contains tmp list that is why its size is 1
Pshemo
  • 122,468
  • 25
  • 185
  • 269
1

This line of code

result.add(temp);

Adds a reference to temp to result, the next line

temp.clear(); // <-- here

clears temp. I think you wanted a copy of temp (so that you could then clear temp without altering result) so,

result.add(new ArrayList<Integer>(temp)); // <-- copy temp.

Then clearing temp will not change the values in result.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
1

temp is a reference to an ArrayList object.

ArrayList<Integer> temp;

This add the reference to the result List.

result.add(temp);  // adds a copy of the reference, not a copy of the list.

This clear the original and only list (apart from the result list)

temp.clear();

Note: Java only has references and primitives, there is no other types.

How could I do to avoid this situation? copy the temp list?

for every new list you want, create a new one. Instead of temp.clear() call

temp = new ArrayList<>();

Ideally, you shouldn't even reuse the local variable unless it has the same purpose.

// don't use temp again.
List<Integer> temp2 = new ArrayList<>();

BTW I advocate that you re-use mutable objects to maximise performance. You should only do this after you have measured this a problem for your allocation rate and you know what you are doing.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130