Вы, кажется, неправильно понимаете, как работает arraylist.
new ArrayList<>(100)
не закрывает список. 100 - это просто подсказка.
ArrayList определяется как разрешающий * бесконечный * рост, а не имеет возможности ограничивать количество элементов, которые могут быть в них .
ArrayList работает «под капотом», имея массив, содержащий ваши элементы. Проблема в том, что java не позволяет массивам увеличиваться или уменьшаться. ArrayList решает эту проблему с помощью двух приемов:
- За счет внутреннего отслеживания длины ArrayList, ArrayList impl может использовать «слишком большой» массив.
- Если вы вы заполнили свой arrayylist таким образом, чтобы в нем было столько элементов, сколько «резервный массив большой», и вы добавляете еще один элемент, у arraylist проблема - резервный массив вне места. Затем ArrayList создаст новый массив большего размера, скопирует все элементы из старого массива, теперь добавит новый элемент (поскольку есть место; этот новый массив больше), а затем избавится от старого массива.
Единственное, что 100
делает в вашем конструкторе, - это подсказка: насколько большим должен быть изначально сделан резервный массив. Из коробки (всего new ArrayList<>()
) вы получаете подсказку по умолчанию 10.
Попробуйте! запустите это:
List<String> list = new ArrayList<String>(100);
for (int i = 0; i < 200; i++) list.add("" + i);
System.out.println(list.size());
Этот код будет нормально компилироваться, работать нормально и печатать 200. Таким образом, доказывая, что «100» не имеет абсолютно ничего общего с ограничением размера этого списка.
Итак, как вы можете ограничить размер Arraylist?
Нет. Arraylist не может этого сделать. Вместо этого вы оборачиваете или расширяете. Для серьезных кодовых баз я настоятельно рекомендую обертывать, но для простого упражнения расширение может сделать ваш код немного короче:
public class LimitedList<T> extends ArrayList<T> {
private final int limit;
public LimitedList(int limit) {
this.limit = limit;
}
@Override public boolean add(T in) {
if (size() >= limit) throw new IllegalStateException("List is full");
super.add(in);
}
@Override public boolean addAll(Collection<T> in) {
// left as an exercise for the reader
}
@Override public boolean addAll(int index, Collection<T> in) {
// left as an exercise for the reader
}
@Override public boolean add(int idx, T in) {
// left as an exercise for the reader
}
@Override public List<T> subList(int from, int to) {
// this one gets complicated!
// let's just not allow it.
throw new UnsupportedOperationException();
}
public int available() {
return limit - size();
}
}
NB: Как видите, вы должны быть очень осторожны и переопределять каждый метод, который может увеличить список; вот почему создание нового типа, который вообще не расширяет ArrayList, а вместо этого имеет 1 поле типа ArrayList (и, конечно, 1 поле типа int для ограничения), может быть лучше: теперь вам явно нужно подумать о каждый список методов имеет, вместо того, чтобы молиться, вы покрыли все те, которые добавляют вещи.
*) ну, прагматично говоря, у вас не может быть более 2 ^ 31-1 элементов.