Ссылки на переменные Java при использовании списков - PullRequest
1 голос
/ 20 февраля 2012

Просто вопрос мысли здесь.В C ++ я мог бы сделать следующее:

vector<vector<string> > data;
// add data into data
//..

data[0].push_back( "somedata" );

И я ожидал бы, что somedata будет записан в векторный массив, потому что запись [] дает мне доступ к объекту по ссылке.А как насчет Java?Если бы я:

List<List<String>> data = new ArrayList<List<String>>();
// add data into data
//..
data.get(0).add( "somedata" );

Это действительно записало бы somedata в объект данных?Или он создаст новую копию элемента в data (0), добавит к этому somedata, и затем этот объект исчезнет в GC когда-нибудь по линии?

Ответы [ 3 ]

3 голосов
/ 20 февраля 2012

ArrayList представляет собой список, резервное копирование которого осуществляется массивом (для обеспечения произвольного доступа), в этом списке хранятся ссылки на реальные элементы, поэтому при добавлении нового элемента, как вы упомянули, ссылка на него будет добавлена ​​в ArrayList (и резервный массив будет указывать на этот элемент списка).

2 голосов
/ 20 февраля 2012

Вы должны сначала понять, что List, String и т. Д. В Java, эти типы являются ссылочными типами. Их значения являются ссылками, которые являются указателями на объекты. Таким образом, List<List<String>> в Java будет наиболее эквивалентно vector<vector<string *> *> * в C ++. Вы не можете иметь прямое «значение объекта» в Java, как вы можете в C ++; объекты всегда скрыты за указателем.

Итак, чтобы ответить на ваш вопрос, да, код Java, который вы показываете, работает, но по совершенно другим причинам. В вашем Java-коде у вас есть список ссылок (указателей). Вы хотите изменить материал в объекте, на который указывает один из этих указателей, но вам не нужно изменять сам указатель. Таким образом, нет необходимости возвращать элемент по ссылке. Достаточно вернуть элемент (указатель) по значению.

Ваш вопрос "Будет ли это записывать некоторые данные в объект данных?" вроде двусмысленно. Код изменяет объект, на который указывает первый элемент списка. Является ли это модификацией самого объекта списка, зависит от того, что вы считаете «частью» объекта. Как объяснялось ранее, объект list содержит коллекцию указателей на объекты. Должны ли объекты, на которые указывают эти указатели, считаться «частью» объекта списка? На один и тот же объект может быть много указателей. Таким образом, если вы считаете, что он является частью контейнера, то что происходит, когда в нескольких контейнерах есть указатели на один и тот же объект, является ли объект частью всех этих контейнеров одновременно?

Ответ на вопрос «Или он создаст новую копию элемента в data (0)» заключается в том, что он создает копию указателя, который является первым элементом. Он не создает копию объекта, на который указывает указатель.

1 голос
/ 20 февраля 2012

Почти. Шаблон, который вам нужен:

List<List<String>> data = new ArrayList<List<String>>();
data.add(new List<String>());
data.get(0).add( "somedata" );

Первая строка создает только «внешний» список списков; вам нужно заполнить его одним или несколькими списками (строк), прежде чем вы сможете добавить данные во внутренние списки.

...