Параметр ArrayList не обновляется во время рекурсии

#java #recursion #arraylist

#java #рекурсия #arraylist

Вопрос:

Я думал, что когда ArrayList передается в качестве параметра и обновляется во время рекурсии, ArrayList изменяется во всех кадрах стека рекурсии. Это неверно?

Я пытаюсь передать пустой ArrayList, а затем заполнить его перестановками слова. Я понимаю, что мне не нужно передавать пустой ArrayList в качестве параметра и вместо этого я мог бы вернуть ArrayList из этого метода, но мне интересно, неверно ли мое понимание того, как объекты хранятся и обновляются во время рекурсии.

 public static void findPermutations(String str, ArrayList<String> l, int from, int to, StringBuilder sb){

    if(from 1 == to){
      l.add("" str.charAt(from));
      return;
    }

    if(from 2 == to){
      l.add("" str.charAt(from) str.charAt(from 1));
      l.add("" str.charAt(from 1) str.charAt(from));
      return;
    }

    char curr = str.charAt(from);
    findPermutations(str,l,from 1,to,sb);

    ArrayList<String> newList = new ArrayList<String>();

    for(String s: l){      
      for(int i=0; i<=s.length(); i  ){
        sb.append(s.substring(0,i));
        sb.append(curr);
        sb.append(s.substring(i));
        newList.add(sb.toString());
        sb.setLength(0);
      }
    }

    //Making a copy of the arraylist
    //Shouldn't it update in the other recursion call stacks as well?

    l=new ArrayList<String>();
    for(String s:newList){
      l.add(s);
    }
  }
 

Комментарии:

1. почему вы инициализируете l в методе?

2. Если у нас есть «abcd», после выполнения базового варианта ArrayList l содержит «cd» и «dc». Затем я добавляю b к каждой позиции в каждой из строк и перезаписываю массив l, заставляя его ссылаться на новый Arraylist, а затем помещая в него строки из нового списка.

Ответ №1:

Хотя список передается по ссылке, l он ссылается только на ссылку. Когда вы это делаете l=new ArrayList<>() , вы просто обновляете l , чтобы указать на новый экземпляр. Исходный список не изменяется, и l s, расположенные дальше в стеке рекурсии, по-прежнему ссылаются на исходный список.

Ответ №2:

 //Making a copy of the arraylist
//Shouldn't it update in the other recursion call stacks as well?

l.clear(); // Do you really want to do this? 
           // It is analogous to the l = new ArrayList<>(), 
           // but it throws away the previous work.
l.addAll(newList);
 

Это изменение обновляет все переменные, которые содержат ссылку на l на протяжении всей рекурсии.