#java #android #arraylist
#java #Android #arraylist
Вопрос:
Я разрабатываю проект Android. Прежде всего, я не разработчик Java. Теперь я хочу кое-что узнать о программировании на Java, особенно о ArrayList.
Вот мой код:
ArrayList<Bitmap> previewBitmaps = new ArrayList<Bitmap>();
//initialize values - total 3 elements
previewBitmaps.remove(2);
ArrayList<Bitmap> temp = new ArrayList<Bitmap>();
temp = previewBitmaps;
previewBitmaps.removeAll(previewBitmaps);
//here temp size become zero because previewBitmaps cleared
Как вы можете видеть в приведенном выше коде, я удаляю элемент из previewBitmaps, затем я назначил остальные 2 элемента для temp. Таким образом, размер temp будет равен 2. Затем я очищаю previewBitmaps. Таким образом, размер previewBitmaps становится равным 0. Но проблема в том, что размер temp также становится равным 0. Почему?
На самом деле размер temp должен быть 2. Верно? Что мне не ясно, так это то, назначена ли она в качестве ссылочной переменной в C? Почему? Как я могу очистить эту ссылку?
Ответ №1:
Здесь temp = previewBitmaps;
вы присваиваете адрес памяти вашего previewBitmaps
ArrayList temp
. Это означает, что они оба указывают на один и тот же адрес памяти. Каждое действие, которое вы выполняете с одним, будет применяться к обоим, потому что они указывают на один и тот же объект в памяти.
Если вы хотите создать новую копию ArrayList, вы можете использовать это: temp = new ArrayList(previewBitmaps);
Комментарии:
1. О, спасибо. Но в C # temp = previewBitmaps; не будет указывать на тот же адрес памяти. Верно?
2. Я не знаю о C #, но я думаю, что это, скорее всего, будет указывать на тот же адрес памяти.
3. Я знаю о c #, и это то же самое с java там 😉
4. Да, я так и думал.
Ответ №2:
Потому что, когда вы назначаете один непримитивный объект другому, на самом деле java заставляет обе эти переменные указывать на одно место в памяти. При изменении данных в памяти будут затронуты обе эти переменные .
Только примитивный тип не действует так, например, для переменной int такого не произойдет, но для всех непримитивных типов это так 😉
Примитивными типами являются int, float, char, …
Ответ №3:
Ваша проблема в основном: не пытайтесь изучать программирование на Java и Android одновременно.
Пример:
ArrayList<Bitmap> previewBitmaps = new ArrayList<Bitmap>();
создает новую пустую карту. Так же:
ArrayList<Bitmap> temp = new ArrayList<Bitmap>();
но ваша следующая строка
temp = previewBitmaps;
отбрасывает список, который вы создали на предыдущем шаге. Исчезла. Какой смысл создавать новый список, чтобы потом его выбросить ?!
Происходит то, что две переменные previewBitmaps и temp указывают на одну и ту же ссылку. Таким образом, вы не манипулируете двумя разными списками, а только одним списком впоследствии.
Если ваша идея заключалась в создании «временной» копии первого списка; вы могли бы делать
List<Bitmap> temp = new ArrayList<>(previewBitmps);
вместо этого (приведенное выше создает новый список, содержащий все элементы другого списка).
И, пожалуйста, обратите внимание: в качестве типов вы должны предпочесть использовать более абстрактные интерфейсы, такие как List . Вы используете только конкретный тип (например, ArrayList при создании объектов); после этого вы должны обращаться к объектам только с помощью интерфейса списка.
Таким образом: сначала сосредоточьтесь на таких основах Java! В противном случае ваш опыт работы с Android будет очень коротким и разочаровывающим. Поскольку вы будете переходить от одной проблемы к следующей. Научитесь сканировать, прежде чем пытаться запустить.
Ответ №4:
Для вас, чтобы установить значения previewBitmaps в temp. Возможно, вы захотите использовать temp.addAll(previewBitmaps);
Ответ №5:
previewBitmaps — это ссылочные переменные, которые указывают на объект. Теперь, когда вы удаляете элемент в позиции 2, объект (список) приобретает размер 2. Теперь, когда вы пишете ArrayList<Bitmap> temp = new ArrayList<Bitmap>()
, он создает новый объект в кучной памяти, а ссылочная переменная temp указывает на этот новый объект. Затем вы вызываете temp = previewBitmaps
. Теперь temp указывает на тот же объект, на который указывает previewBitmaps. Поэтому, когда вы вызываете
previewBitmaps.removeAll(previewBitmaps);
она удаляет все элементы из объекта, на который указывают обе ссылочные переменные, т.е. previewBitmaps и temp .
Ответ №6:
Это происходит, когда вы присваиваете две ссылки одному и тому же объекту. Вам нужно создать глубокий клон текущего ArrayList вместо мелкого.
for(Bitmap b: previewBitmaps){
temp.add(b.clone())
}
Выполнение temp = previewBitmaps.clone()
не поможет, поскольку оно создаст новый ArrayList
, но оба списка будут указывать на одни и те же объекты внутри. Это известно как мелкий клон.