#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 на протяжении всей рекурсии.