Как изменить размер ArrayList

Я родом из C++ и хочу иметь матрицу

ArrayList<arrayList<E>> javamatrix 

В С++ я бы просто сделал

std::vector<std::vector<T> > cppmatrix;
std::vector<T>vcol(cols);
cppmatrix.resize(rows,vcol);

Я не могу найти встроенную функцию resize() для ArrayLists для этой задачи, поэтому должен ли я использовать другую коллекцию? Разве это невозможно сделать, кроме как использовать циклы for с javamatrix.add()?


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


person Ismail Marmoush    schedule 13.11.2010    source источник
comment
Почему вам нужно изменить его размер? ArrayLists расширяются автоматически, когда это необходимо.   -  person Jesper Fyhr Knudsen    schedule 13.11.2010
comment
Кстати говоря, я мог бы поклясться, что векторы STL также автоматически изменяют размер по мере того, как вы добавляете в них больше данных.   -  person Dave McClelland    schedule 13.11.2010
comment
@Arkain Я понимаю, что вы имеете в виду, но когда вы сталкиваетесь со структурой данных резервирования, вам нужно сначала указать размер массива, прежде чем размещать элемент, который необходимо поместить в определенный индекс.   -  person neferpitou    schedule 14.01.2015


Ответы (4)


Не существует эквивалента resize, который автоматически создает и добавляет элементы. Вы должны сделать это сами. Однако ensureCapacity эквивалентен вектору reserve. Это гарантирует, что у вас будет место, но не изменит фактический размер.

person Matthew Flaschen    schedule 13.11.2010

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

Из документации:

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

person Dave McClelland    schedule 13.11.2010
comment
Возможно, вы захотите изменить размер, если хотите поместить объект немного дальше конца массива и заполнить пробел объектами по умолчанию. Я предполагаю, что это не совсем возможно с семантикой памяти/объекта, которую выбрала Java. - person Timmmm; 25.01.2012
comment
Другой вариант использования метода resize() — если вы хотите удалить все элементы за пределами определенного индекса. Конечно, вы можете использовать remove() для цикла for, но resize() более удобен и может быть более оптимальным. - person Blackhex; 11.11.2012
comment
Изменение размера необходимо, когда у вас есть расширяемая таблица поиска. Например. у вас до сих пор индексы до 30 и выходит индекс 250. - person Chameleon; 06.07.2018

В основном операция «resize()» не требуется, потому что (а) ArrayList автоматически изменяет размер при добавлении элементов и (б) неясно, какие значения вы будете хранить в ArrayList‹>, например. 'null' не очень полезен. Например. в вашем случае вам, вероятно, все равно понадобится цикл для создания объектов MatrixCell.

Для тех читателей, которые хотят знать, как изменить размер ArrayList, чтобы сделать его меньше, меня озадачивает, почему ArrayList был разработан без метода resize(). Возможно, это связано с тем, что начинающие программисты, скорее всего, увидят этот метод и не поймут, что ArrayList‹> автоматически изменяет размеры.

В Java эта идиома работает для уменьшения размера ArrayList‹>:

    list.subList(n,list.size()).clear();

Это работает, потому что «subList» возвращает список, поддерживаемый исходным ArrayList‹>, поэтому «clear()» работает с исходным «ArrayList‹>».

person Tim Cooper    schedule 23.04.2013
comment
Очень плохой ответ, который утверждает, что изменение размера не требуется. Есть масса причин иметь resize(). Например, вам нужен массив размером n, и вы хотите иметь возможность произвольного доступа к массиву. Без изменения размера, чтобы сделать его размером n в первую очередь, вы не можете сделать arr.get(some_index) и arr.set(some_index, obj). - person Kan Li; 17.04.2014
comment
@icando Я полагаю, вы думаете о разреженных массивах, и я согласен, что это тот случай, когда «resize ()» был бы полезен, хотя карта может быть лучше, если она действительно разреженная. Если вы действительно хотите, чтобы все ячейки в массиве были заполнены, вам нужно будет инициализировать каждую запись какой-либо действительной ссылкой, и в этом случае вам все еще нужен цикл. - person Tim Cooper; 18.04.2014
comment
вы также можете расширить коллекцию следующим образом: collection.addAll(Collections.nCopies(n, defaultElement)); возможно, не так элегантно, как цикл, но работает - person Jayen; 04.01.2015
comment
@Tim Cooper: Чем разреженный массив уступает карте? Я всегда предполагал, что разреженный массив — это карта, но с конкретным собственным индексом вместо целочисленного индекса. - person Robin Davies; 04.05.2018
comment
Не уверен, что плотная и непостижимая идиома list.subList(n,list.size()).clear() действительно лучше, чем while (list.size() › size) list.remove(list.size()-1) . - person Robin Davies; 04.05.2018

Я знаю, что этот вопрос уже очень старый, но эта ссылка может помочь java arraylist гарантировать неработоспособность , Код добавляет значение «Null», чтобы настроить текущий размер.

Вместо того, чтобы использовать только sureCapacity, вы можете использовать sureSize

public static void ensureSize(ArrayList<?> list, int size) {

    list.ensureCapacity(size);
    while (list.size() < size) {
        list.add(null);
    }
}
person neferpitou    schedule 14.01.2015
comment
Вы также можете просто использовать list.addAll(Collections.nCopies(size, null)); - person Paul Weibert; 03.05.2020