Как я могу вырезать ArrayList из ArrayList в Java?

Как получить фрагмент массива ArrayList в Java? В частности, я хочу сделать что-то вроде этого:

ArrayList<Integer> inputA = input.subList(0, input.size()/2);
// where 'input' is a prepouplated ArrayList<Integer>

Итак, я ожидал, что это сработает, но Java возвращает a List - поэтому он несовместим. И когда я пытаюсь это сделать, Java не позволит мне. Мне нужно ArrayList - что я могу сделать?

Ответ 1

В Java рекомендуется использовать типы интерфейсов, а не конкретные классы в API.

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

Вот как выглядит ваш код:

List input = new ArrayList(...);

public void doSomething(List input) {
   List inputA = input.subList(0, input.size()/2);
   ...
}

this.doSomething(input);

Ваше предлагаемое "решение" проблемы было/есть следующее:

new ArrayList(input.subList(0, input.size()/2))

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


Если вы ограничены API, которые вы не можете изменить, так что вы должны объявить inputA как ArrayList, вы можете реализовать собственный подкласс ArrayList, в котором возвращается метод subList подкласс ArrayList. Однако:

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

Решение "скопировать массив" более практично... учитывая, что это не истинные срезы.

Ответ 2

Если нет существующего метода, то я думаю, вы можете перебирать от 0 до input.size()/2, беря каждый последовательный элемент и добавляя его в новый ArrayList.

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

Ответ 3

Я нашел способ, если вы знаете startIndex и endIndex элементов, которые нужно удалить из ArrayList

Пусть al будет исходным ArrayList и startIndex, endIndex будет начальным и конечным индексом, которые должны быть удалены из массива соответственно:

al.subList(startIndex, endIndex + 1).clear();

Ответ 4

Вот как я это решил. Я забыл, что подсписка была прямой ссылкой на элементы в исходном списке, поэтому имеет смысл, почему это не сработает.

ArrayList inputA = новый ArrayList (input.subList(0, input.size()/2));