Подтвердить что ты не робот

Сокращение ArrayList до нового размера

Нужно ли мне самому реализовать его?

private void shrinkListTo(ArrayList<Result> list, int newSize) {
  for (int i = list.size() - 1; i >= newSize; --i)
  list.remove(i);
}
4b9b3361

Ответ 1

Создайте sublist с диапазоном элементов, которые вы хотите удалить, а затем вызовите clear в возвращаемом списке.

list.subList(23, 45).clear()

Этот подход упоминается как идиома в документации для List и ArrayList.


Здесь приведен пример кода, протестированного полностью в модуле!

// limit yourHappyList to ten items
int k = yourHappyList.size();
if ( k > 10 )
    yourHappyList.subList(10, k).clear();
    // sic k, not k-1

Ответ 2

альтернативно вы можете использовать метод subList:

public static <T> List<T> shrinkTo(List<T> list, int newSize) {
    return list.subList(0, newSize - 1);
}

Ответ 3

использовать Метод ArrayList # removeRange():

protected void removeRange (int fromIndex,                            int toIndex)

Удаляет из этого списка все элементы, индекс которых находится в пределах отIndex, inclusive и toIndex, исключительный. Сдвигает любые последующие элементы влево (уменьшает их индекс). Этот вызов сокращает список с помощью элементов (toIndex - fromIndex). (Если toIndex == fromIndex, эта операция не имеет эффекта.)

затем используйте метод ArrayList # trimToSize():

Обрезает емкость этого экземпляра ArrayList как текущий текущий список. Приложение может использовать эту операцию для сведения к минимуму хранения экземпляра ArrayList.

Ответ 4

Мое решение:

public static void shrinkTo(List list, int newSize) {
    int size = list.size();
    if (newSize >= size) return;
    for (int i = newSize; i < size; i++) {
        list.remove(list.size() - 1);
    }
}

Просто используйте:

shrinkTo(yourList, 6);

Ответ 5

Есть еще одно соображение. Возможно, вы захотите уклониться от использования ArrayList в вашей сигнатуре метода и вместо этого работать с интерфейсом List, поскольку он связывает вас с реализацией ArrayList, что затрудняет внесение изменений в строку, если вы обнаружите, что для Например, LinkedList более подходит для ваших нужд. Предотвращение этой жесткой связи действительно связано с затратами.

Альтернативный подход может выглядеть так:

private void shrinkListTo(List<Result> list, int newSize) {
  list.retainAll(list.subList(0, newSize);
}

К сожалению, метод List.retainAll() не является обязательным для реализации подклассов, поэтому вам нужно catch a UnsupportedOperationException,, а затем сделать что-то еще.

private void shrinkListTo(List<Result> list, int newSize) {
  try {
    list.retainAll(list.subList(0, newSize);
  } catch (UnspportedOperationException e) {
     //perhaps log that your using your catch block version.
     for (int i = list.size() - 1; i >= newSize; --i)
        list.remove(i);
     }
  }
}

Это не так прямо, как ваш оригинал. Если вы не привязаны к экземпляру списка, который вы проходите, вы можете так же легко вернуть новый экземпляр, вызвав subList(int start, int end), и вам даже не понадобится делать метод. Это также будет более быстрой реализацией, так как (в Java 6) вы получите экземпляр AbstractList.SubList, который содержит ваш список, смещение в нем и размер. Итерации не потребуется.

Если вас интересуют аргументы для кодирования для интерфейсов вместо классов, см. эту любимую статью Аллена Гобуфа