Размеры динамического массива Java? - PullRequest
89 голосов
/ 30 октября 2009

У меня есть класс - xClass, который я хочу загрузить в массив xClass, поэтому я объявил:

xClass mysclass[] = new xClass[10];
myclass[0] = new xClass();
myclass[9] = new xClass();

Однако я не знаю, понадобится ли мне 10. Мне может понадобиться 8 или 12 или любой другой номер по этому вопросу. Я не буду знать до времени выполнения. Могу ли я изменить количество элементов в массиве на лету? Если да, то как?

Ответы [ 18 ]

148 голосов
/ 30 октября 2009

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

int oldItems[] = new int[10];
for (int i=0; i<10; i++) {
  oldItems[i] = i+10;
}
int newItems[] = new int[20];
System.arraycopy(oldItems, 0, newItems, 0, 10);
oldItems = newItems;

Если вы окажетесь в такой ситуации, я настоятельно рекомендую вместо этого использовать коллекции Java. В частности ArrayList по существу оборачивает массив и заботится о логике для увеличения массива по мере необходимости:

List<xClass> mysclass = new ArrayList<xClass>();
myclass.add(new xClass());
myclass.add(new xClass());

Обычно ArrayList является предпочтительным решением для массива в любом случае по нескольким причинам. Во-первых, массивы изменчивы. Если у вас есть класс, который делает это:

class Myclass {
  private int items[];

  public int[] getItems() { return items; }
}

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

class Myclass {
  private List<Integer> items;

  public List<Integer> getItems() { return Collections.unmodifiableList(items); }
}
24 голосов
/ 30 октября 2009

В массиве Java фиксированная длина.

Вы можете использовать List для хранения значений и при необходимости вызывать метод toArray Смотрите следующий образец:

import java.util.List;
import java.util.ArrayList;
import java.util.Random;

public class A  {

    public static void main( String [] args ) {
        // dynamically hold the instances
        List<xClass> list = new ArrayList<xClass>();

        // fill it with a random number between 0 and 100
        int elements = new Random().nextInt(100);  
        for( int i = 0 ; i < elements ; i++ ) {
            list.add( new xClass() );
        }

        // convert it to array
        xClass [] array = list.toArray( new xClass[ list.size() ] );


        System.out.println( "size of array = " + array.length );
    }
}
class xClass {}
8 голосов
/ 30 октября 2009

Как уже говорили другие, вы не можете изменить размер существующего массива Java.

ArrayList - это наиболее близкий стандарт Java к массиву динамического размера. Однако в ArrayList (на самом деле, в интерфейсе List) есть некоторые вещи, которые не похожи на массив. Например:

  • Вы не можете использовать [ ... ] для индексирования списка. Вы должны использовать методы get(int) и set(int, E).
  • ArrayList создается с нулевыми элементами. Вы не можете просто создать ArrayList с 20 элементами и затем вызвать set(15, foo).
  • Вы не можете напрямую изменить размер ArrayList. Вы делаете это косвенно, используя различные методы add, insert и remove.

Если вы хотите что-то более похожее на массив, вам нужно разработать собственный API. (Может быть, кто-то может подключиться к существующей сторонней библиотеке ... Я не смог найти одну за 2 минуты "исследования" в Google :-))

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

ArrayList<T> tmp = new ArrayList<T>();
while (...) {
    tmp.add(new T(...));
}
// This creates a new array and copies the element of 'tmp' to it.
T[] array = tmp.toArray(new T[tmp.size()]);
6 голосов
/ 18 декабря 2013

Вы можете использовать ArrayList:

import java.util.ArrayList;
import java.util.Iterator;

...

ArrayList<String> arr = new ArrayList<String>();
arr.add("neo");
arr.add("morpheus");
arr.add("trinity");
Iterator<String> foreach = arr.iterator();
while (foreach.hasNext()) System.out.println(foreach.next());
6 голосов
/ 30 октября 2009

Вы устанавливаете количество элементов на то, что хотите во время создания:

xClass[] mysclass = new xClass[n];

Затем вы можете инициализировать элементы в цикле. Я предполагаю, что это то, что вам нужно.

Если вам нужно добавить или удалить элементы в массиве после его создания, вам придется использовать ArrayList.

3 голосов
/ 15 апреля 2013

Arrays.copyOf() метод имеет много опций, чтобы решить проблему с динамическим увеличением длины массива.

Java API

2 голосов
/ 04 сентября 2012

Я рекомендую вместо этого использовать векторы. Очень прост в использовании и имеет много предопределенных методов для реализации.

import java.util.*;

Vector<Integer> v=new Vector<Integer>(5,2);

для добавления элемента просто используйте:

v.addElement(int);

В (5,2) первые 5 - это начальный размер вектора. Если вы превысите исходный размер, вектор вырастет на 2 места. Если оно снова превысит, то оно снова увеличится на 2 места и т. Д.

2 голосов
/ 30 октября 2009

Как говорят другие пользователи, вам, вероятно, нужна реализация java.util.List.

Если по какой-то причине вам, наконец, нужен массив, вы можете сделать две вещи:

  • Использовать список, а затем преобразовать его в массив с помощью myList.toArray ()

  • Использовать массив определенного размера. Если вам нужно больше или меньше размера, вы можете изменить его с помощью методов java.util.Arrays.

Лучшее решение будет зависеть от вашей проблемы;)

2 голосов
/ 30 октября 2009

Да, оберните его и используйте фреймворк Коллекций.

List l = new ArrayList();
l.add(new xClass());
// do stuff
l.add(new xClass());

Затем используйте List.toArray () при необходимости или просто перебирайте указанный список.

1 голос
/ 12 декабря 2015

Размеры Java Array фиксированы. Вы не можете создавать динамические массивы, как в C ++.

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