user1896796
user1896796

Reputation: 749

Understanding the logic behind clear() in ArrayList

I am using below program to find the subsequences in an given given list. When I am using clear() , the values in li is also getting cleared. Hence, I am creating a new reference everytime.

I wanted to understand the logic behind this. Am I using it wrong? Or it is the reference that I am adding to my li?

 public static int getTheSubseq(List<Integer> AList){
      //  int[][] subsequences = new int[][];
      List<List<Integer>> li = new ArrayList<>();
      List<Integer> temp = new ArrayList<>();

      for (int i = 0; i < AList.size(); i++){
          for(int j =i+1; j < AList.size(); j++){
              temp.add(AList.get(i));
              temp.add(AList.get(j));
              li.add(temp);
              temp = new ArrayList<>();
              //temp.clear();
          }
      }
      System.out.println(li);
      return 1;

    }

Upvotes: 4

Views: 86

Answers (4)

Tomaz Mazej
Tomaz Mazej

Reputation: 465

Try doing this:

public static int getTheSubseq(List<Integer> AList){
  //  int[][] subsequences = new int[][];
  List<List<Integer>> li = new ArrayList<>();
  List<Integer> temp;

  for (int i = 0; i < AList.size(); i++){
      for(int j =i+1; j < AList.size(); j++){
          temp = new ArrayList<>();
          temp.add(AList.get(i));
          temp.add(AList.get(j));
          li.add(temp);
      }
  }
  System.out.println(li);
  return 1;

}

Upvotes: 0

Mureinik
Mureinik

Reputation: 311163

When you call .clear() (or any other method for that matter), you're operating on the same refernece. Here, if you don't create a new list each iteration, you're adding the list referenced to by temp to li. When you call clear(), they are "all" cleared, since they all point to the same object. When you create a new list each iteration, you have different objects, and can operate on them independently.

Upvotes: 1

Eran
Eran

Reputation: 393781

Regardless of whether or not you are calling temp.clear(), if you add to li multiple times a reference to the same List object, li will contain multiple references to the same List object, which means li.get(0) == li.get(1), li.get(0) == li.get(2), and so on...

Making changes in one of these inner Lists will be reflected in all the other inner Lists, since there's just one List referenced multiple times.

Therefore, assigning a new ArrayList instance to temp in each iteration of your loop (before adding it to li) is the right thing to do.

I'd make a slight change though - create the new inner List just before adding it to the outer List:

for (int i = 0; i < AList.size(); i++){
    for(int j =i+1; j < AList.size(); j++){
        List<Integer> temp = new ArrayList<>();
        temp.add(AList.get(i));
        temp.add(AList.get(j));
        li.add(temp);
    }
}

Upvotes: 3

Federico klez Culloca
Federico klez Culloca

Reputation: 27119

Adding the element to li doesn't make a copy. So when you call clear() you'll have both temp and an element inside li that point to the same object.

You may want to just declare temp inside the inner loop, so you get a fresh one every time without needing to call clear().

Upvotes: 2

Related Questions