mk7644
mk7644

Reputation: 33

clearing values of sublist, clears values of parentlist in java

List<List<Integer>> li = new ArrayList<List<Integer>>();
List<Integer> li1 = new ArrayList<Integer>();

for (int k = 0; k < 5; k++) {
    li1.clear();// it’s clearing values of the parent List as well
    for (int j = 0; j < 4; j++) {
       if (arr[k][j].equals("H")) {
         li1.add(j);
       }
    }
    if (li1.size() > 0)
       li.add(li1);
}

Upvotes: 0

Views: 126

Answers (4)

Eklavya
Eklavya

Reputation: 18430

You are using the same reference and add in the parent list. Try to create new ArrayList inside the loop rather creating outside and clearing everytime.

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

instead of

li1.clear();

Upvotes: 1

Anonymous
Anonymous

Reputation: 86272

The others have nicely explained what went wrong in your code. The fine solution is not declaring the child list until you need it, that is, declare it inside the outer loop.

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

    for (int k = 0; k < 5; k++) {
        List<Integer> childList = new ArrayList<>();
        for (int j = 0; j < 4; j++) {
            if (arr[k][j].equals("H")) {
                childList.add(j);
            }
        }
        if (! childList.isEmpty()) {
            parentList.add(childList);
        }
    }

Now I believe that everyone can see that the different child lists cannot interfere with each other. And now you need no copying of any lists.

I made a few other minor stylistic improvements to your code.

Upvotes: 1

Vishal
Vishal

Reputation: 404

You are adding the reference of child list to parent list. So when you clear the content of the child list, parent list will have nothing but a reference to the child list.

In short-

If subresult is [1,2,3] and you add this in result, then result = [1,2,3]

But now if you remove 3 from subresult, then result also becomes [1,2]

Similarly, clearing subresult also removes from the result list.

So in order to avoid that,

result.add(new ArrayList(subresult));

This creates a new List object with the values of the passed in list.

Upvotes: 0

Unmitigated
Unmitigated

Reputation: 89224

You need to clone the List or create a new ArrayList with its elements so that they do not refer to the same object.

if (li1.size() > 0)
    li.add(new ArrayList<>(li1));

Upvotes: 0

Related Questions