Существует ли расширяемый список ссылок на объекты в Java? - PullRequest
1 голос
/ 28 октября 2008

В Java мы всегда можем использовать массив для хранения ссылки на объект. Затем у нас есть ArrayList или HashTable, который автоматически расширяется для хранения объектов. Но кто-нибудь знает собственный способ иметь автоматически расширяемый массив ссылок на объекты?

Редактировать: я имею в виду, что я хочу знать, есть ли в Java API какой-то класс с возможностью хранить ссылки на объекты (но не хранить фактический объект, как это делают XXXList или HashTable) И возможность автоматического расширения.

Ответы [ 8 ]

5 голосов
/ 28 октября 2008

Java-массивы по определению имеют фиксированный размер. Если вам нужен автоматический рост, вы используете классы XXXList.

РЕДАКТИРОВАТЬ - вопрос прояснился немного

Когда я только начинал изучать Java (исходя из C и C ++), это было, вероятно, одной из первых вещей, которые взволновали меня. Надеюсь, я смогу пролить немного света.

В отличие от C ++, массивы объектов в Java не хранят объекты. Они хранят ссылки на объекты.

В C ++, если вы объявили нечто похожее на:

String myStrings[10];

Вы получите 10 строковых объектов. На этом этапе было бы совершенно законно сделать что-то вроде println (myStrings [5] .length); - вы получите '0' - конструктор по умолчанию для String создает пустую строку длиной 0.

В Java, когда вы создаете новый массив, вы получаете пустой контейнер, который может содержать 10 строковых ссылок. Итак, звонок:

String[] myStrings = new String[10];
println(myStringsp[5].length);

выдаст исключение нулевого указателя, потому что вы еще не поместили ссылку String в массив.

Если вы пришли из C ++, подумайте, что новая String [10] эквивалентна новой (String *) [10] из C ++.

Итак, имея это в виду, должно быть достаточно ясно, почему ArrayList является решением для автоматического расширения массива объектов (и фактически ArrayList реализован с использованием простых массивов, со встроенным алгоритмом роста). при этом выделяет новые расширенные массивы по мере необходимости и копирует содержимое из старого в новое).

На практике на самом деле относительно мало ситуаций, когда мы используем массивы. Если вы пишете контейнер (что-то похожее на ArrayList или BTree), тогда они полезны, или если вы выполняете много низкоуровневых манипуляций с байтами - но на уровне, на котором происходит большая часть разработки, используя один из классов Collections безусловно, предпочтительный метод.

4 голосов
/ 28 октября 2008

Все классы, реализующие Collection, являются расширяемыми и хранят только ссылки: вы не храните объекты, вы создаете их в некотором пространстве данных и манипулируете только ссылками на них, пока они не выйдут из области видимости без ссылки на них.

Вы можете поместить ссылку на объект в две или более Коллекции. Вот как вы можете отсортировать хеш-таблицы и все такое ...

1 голос
/ 28 октября 2008

В Java все переменные объекта являются ссылками. Так

Foo myFoo = new Foo();
Foo anotherFoo = myFoo;

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

1 голос
/ 28 октября 2008

Прямо из Обучающих программ по Java Array на веб-странице Sun:

-> Массив - это контейнерный объект, который содержит fixed количество значений одного типа.

Поскольку размер массива объявляется при его создании, на самом деле нет способа расширить его впоследствии. Вся цель объявления массива определенного размера состоит в том, чтобы выделить только столько памяти, сколько будет использовано при выполнении программы. Что вы могли бы сделать, это объявить второй массив, который является функцией, основанной на размере оригинала, скопировать в нее все исходные элементы и затем добавить необходимые новые элементы (хотя это «автоматический» :)). В противном случае, как вы и некоторые другие отметили, список коллекций является наиболее эффективным способом.

1 голос
/ 28 октября 2008

Что вы подразумеваете под "родным" способом? Если вам нужен расширяемый список объектов, вы можете использовать ArrayList. С коллекциями List у вас есть метод get (index), который позволяет вам получить доступ к объектам в списке по индексу, который дает вам функциональность, аналогичную массиву. Внутренне ArrayList реализован с помощью массива, и ArrayList обрабатывает его автоматическое расширение.

0 голосов
/ 28 октября 2008

Это не очень эффективно, но если вы просто добавляете массив, вы можете использовать Apache Commons ArrayUtils.add () . Возвращает копию исходного массива с дополнительным элементом в нем.

0 голосов
/ 28 октября 2008

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

Вы можете написать

a [0] = 4;
а [1000] = 434;
a [888] = "строка";

0 голосов
/ 28 октября 2008

Нет такой первоклассной языковой конструкции, которая делает то, о чем я знаю, если это то, что вы ищете.

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