Как я могу сделать массив изменяемого размера в Java?

Что лучший способ состоит в том, чтобы сделать массив изменяемого размера в Java? Я пытался использовать Вектор, но это смещает все элементы на то, когда, когда Вы делаете вставку, и мне нужен массив, который может вырасти, но элементы остаются на месте. Я уверен, что существует простой ответ для этого, но меня все еще не совершенно уверен.

12
задан Kevin Crowell 6 April 2010 в 00:42
поделиться

8 ответов

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

Возможно, вы хотите использовать ArrayList вместо Vector.

Они оба предоставляют примерно одинаковый интерфейс, и вы можете заменить элементы обоими из них, вызвав set(idx, element). Это не делает никаких сдвигов. Это также не позволяет вам увеличить массив, хотя: вы можете вставлять только на уже занятые позиции (не превышающие текущий размер массива), чтобы добавить новые элементы в конце вы должны использовать add(element).

Разница между ArrayList и Vector заключается в том, что Vector имеет код синхронизации, который вам, скорее всего, не нужен, что делает ArrayList немного быстрее.

1
ответ дан 2 December 2019 в 04:16
поделиться

Использование замечательных классов в структуре Collections лучше, чем использование массивов. Но в случае, если ваш вопрос с точки зрения «викторины», вот что вы должны сделать. Создайте собственный метод изменить размер, например:

  int[] oldArray = {1,2,3};

  int oldSize = java.lang.reflect.Array.getLength(oldArray);
  Class elementType = oldArray.getClass().getComponentType();
  Object newArray = java.lang.reflect.Array.newInstance(
         elementType,newSize);
  int preserveLength = Math.min(oldSize,newSize);
  if (preserveLength > 0)
      System.arraycopy (oldArray,0,newArray,0,preserveLength);

  oldArray = newArray;
-3
ответ дан 2 December 2019 в 04:16
поделиться

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

1
ответ дан 2 December 2019 в 04:16
поделиться

В качестве альтернативы вы можете использовать ArrayList . Это реализация интерфейса List с изменяемым размером массива.

Использование (с использованием String):

List<String> myList = new ArrayList<String>();
myList.add("a");
myList.add("c");
myList.add("b");

Порядок будет таким, как вы их разместили: a, c, b.

Вы также можете получить отдельный элемент вроде этого:

String myString = myList.get(0);

Что даст вам 0-й элемент: «a».

23
ответ дан 2 December 2019 в 04:16
поделиться
3
ответ дан 2 December 2019 в 04:16
поделиться

Как указал Санджо: « Массив - это статическая структура данных, поэтому они не могут расти ». Интерфейс списка может поддерживаться массивом (например, ArrayList , как указал Кевин в своем сообщении ). Когда структура списка заполнена и в список нужно добавить новый элемент. Затем структура сначала создает новый массив, который может содержать старые элементы плюс новый элемент, который необходимо добавить в список.

Интерфейс списка имеет разные реализации, у всех есть свои плюсы и минусы, и вам следует выбрать ту, которая лучше всего решает вашу проблему.Ниже я попытаюсь кратко изложить, когда и какую реализацию использовать:

Не потокобезопасные реализации:

  • ArrayList : реализация интерфейса List с изменяемым размером массива. Вам следует использовать эту реализацию, когда вы выполняете много операций size, isEmpty, get, set, iterator и listIterator , выполняемых в постоянное время. Операция add выполняется за амортизированное постоянное время, то есть добавление n элементов требует времени O (n). Я думаю, вам следует использовать эту реализацию при выполнении дополнительных поисков ( get () ), а затем при добавлении элементов в список ( add () ).
  • LinkedList : Эта реализация не является резервным массивом, а «связывает» узлы вместе. На мой взгляд, вам следует использовать эту реализацию, когда вы делаете больше add () , а затем get () .

Поточно-ориентированные реализации:

Имейте в виду, что эти реализации списков не являются thread -безопасными, что означает, что можно получить состояния гонки при доступе к ним из нескольких потоков. . Если вы хотите использовать реализации List из нескольких потоков, я бы посоветовал вам изучить пакет java.util.concurrent и использовать реализацию из этого класса.

4
ответ дан 2 December 2019 в 04:16
поделиться

Проверить ArrayList

2
ответ дан 2 December 2019 в 04:16
поделиться

Вероятно, вам следует использовать ArrayList вместо Vector по причинам, объясненным в других ответах.

Однако ...

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

Когда вы выполняете insertElementAt (pos, elem) , у вас специально запрашивается сдвиг элемента. Если вы не хотите, чтобы элементы смещались, вы должны вместо этого использовать set (pos, elem) . Или, если вы хотите добавить элемент в конец вектора, вы также можете использовать add (elem) .

Между прочим, предыдущий абзац применяется ко всем реализациям List , а не только Vector , хотя детали реализации и производительность различаются для разных типов List .

3
ответ дан 2 December 2019 в 04:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: