Копирование данных в ссылку в Java (отсутствие указателя проблемы) - PullRequest
1 голос
/ 20 июля 2010

Итак, у меня есть ArrayList в Java.И то, что я делаю, - это создание нового списка с обновленными значениями.Но я хочу поместить эти новые значения в оригинальный ArrayList.Это важно, потому что я передаю исходную ссылку на массив для объекта, к которому у меня больше нет доступа, но мне нужно обновлять его содержимое.Есть ли способ заставить java скопировать содержимое в текущую ссылку?Надеюсь, это имеет смысл.

Кроме того, я бы предпочел не очищать исходный массив и затем проходить через него, проталкивая в него новое содержимое.

Мне нужно сделать что-то вроде этого:

ArrayList a;
ArrayList *b = a;
//pass b (the pointer) to something
ArrayList c;
*b = c;

Я действительно надеюсь, что понял (псевдо) код на C ++ правильно, или я буду выглядеть довольно глупо = P

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

<code>
Class1{
ArrayList a;
method1(){

a = Class2.getA();
method_that_uses_a(a);
}
}

Class2{
ArrayList getA(){

ArrayList a = new ArrayList

a = getDataFromWebsite();

return a;
}

method1 () класса 1 периодически вызываетсядругой частью кода.Но мне нужна ссылка на то же самое, но содержание, чтобы перейти на новое содержание.

Ответы [ 4 ]

1 голос
/ 20 июля 2010

Я думаю, что ваш вопрос неясен, что вы подразумеваете под

"И то, что я делаю, - это создание нового списка с обновленными значениями. Но я хочу поместить эти новые значения в исходный ArrayList. Это важно, потому что я передаю исходную ссылку на массив для объекта, который я не у меня больше нет доступа к нему, но мне нужно поддерживать его содержимое в актуальном состоянии. Есть ли способ заставить java скопировать содержимое в текущую ссылку? Надеюсь, это имеет смысл. "

Когда вы делаете

List a = new ArrayList
List b = a

у вас есть один объект ArrayList и две ссылки на объект, a и b.

Также обратите внимание, что существует метод addAll, который можно использовать для добавления членов одной коллекции в другую. Обратите внимание, что я полагаю, что addAll не делает глубокую копию, поэтому, если вы используете ее, оба списка имеют копии одной и той же ссылки. Поэтому, если в списке a есть ссылки a1, a2, a3 и вы выполняете b.addAll (a), b теперь имеет ссылки на объекты, на которые указывает a1 ... a3 ...

0 голосов
/ 20 июля 2010

Ваш код C ++ говорит это:

ArrayList a;            //make arraylist
ArrayList *b = a;       //set b to point to same arraylist as a
//pass b somewhere
ArrayList c;            //make arraylist
*b = c;                 //variable b in THIS PROGRAM now points to c. arraylist is unchanged.

Вы хотите обновить массив, а не указатель на него, поскольку этот указатель только «существует» в текущем контексте. Код, который вы передали массиву, в который вы не обращаете внимания, если указатель обратно в who-знает-где теперь указывает на тот же массив, который он использует. Это фактический объект, о котором заботится другой код. Чтобы обновить этот объект, вы можете просто вызвать методы для него, например a.add(bar)

НО это еще не все. Если вы вызываете функцию, которую вы не контролируете (теперь она называется foo), и передаете ее в виде массива, то все в порядке. Но если вы хотите обновить его из кода, вызывающего foo, вы столкнетесь с проблемами. Представьте, что объект, с которым вы работали, может в любое время случайно изменить . Все виды плохого могут случиться. Если вам действительно нужна эта возможность (и мы можем помочь вам судить, если вам это нужно), изучите тему threading.

0 голосов
/ 20 июля 2010

В Java, как я надеюсь, вы уже выяснили, что все переменные являются ссылками. Среди прочего это означает, что если они не назначены объекту, они ни на что не «указывают». Вам необходимо написать:

ArrayList a = new ArrayList();

или не указывает на фактический объект - это просто ноль.

Если вы напишите:

ArrayList a = new ArrayList();
ArrayList b = a;
modify(b);
ArrayList c = b;

тогда есть только один ArrayList. Все переменные a, b и c относятся к нему. Любые изменения, сделанные в методе 'modify', применяются к нему и будут отражены в состоянии a, b и c.

0 голосов
/ 20 июля 2010

Все классы массива предоставляют открытые методы clone (), поэтому, если мелкой копии массива достаточно тогда

return (ElementType[]) myArray.clone();

Делает для красивой, простой, легко читаемой парадигмы. Если "ElementType" является примитивного типа, то нет различия между мелким и глубоким копирование, и если оно является неизменным, то выполнение глубокого копирования будет расточительным. При некоторых других обстоятельствах мелкая копия - это то, что вы бы в любом случае (вы хотите, чтобы получатель мог изменять элементы массива с видимыми для хоста эффектами).

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

...