Недавно столкнулся с необычным поведением у java.util.ArrayList. A именно метод java.util.List.add(int, Object). Предлагаю рассмотреть на примере:
|
1 2 3 4 5 |
public static void main(String[] args) { List list = new ArrayList(5); list.add(4, "9"); System.out.println(list.get(4)); } |
данный код свалится с эксепшеном
|
1 2 3 |
java.lang.IndexOutOfBoundsException: Index: 4, Size: 0 at java.base/java.util.ArrayList.rangeCheckForAdd(ArrayList.java:682) at java.base/java.util.ArrayList.add(ArrayList.java:494) |
Но этот же код отлично отработает с нативным массивом:
|
1 2 3 4 5 |
public static void main(String[] args) { String [] array = new String [5]; array[4] = "9"; System.out.println(array[4]); } |
Казалось бы в чем разница? Может ArrayList инициализируется по своему? Проверил, все в порядке создается настоящий внутренний массив размером который указывается в конструкторе:
|
1 2 3 4 5 6 7 8 9 |
public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); } } |
Остаётся метод add:
|
1 2 3 4 |
public void add(int index, E element) { rangeCheckForAdd(index); ... } |
Как мы видим сразу же идёт проверка диапазона:
|
1 2 3 4 |
private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } |
Другими словами когда мы используем конструктор java.util.ArrayList.ArrayList(int) мы как бы получаем доступ до внутрянки, одновременно с этим ничего больше не получаем взамен. На мой взгляд несколько намешано в архитектуре. Выставлен конструктор только лишь для того, чтобы оказать влияние на внутреннее предствление. И всё.
Так что в очередной раз можно утвердится в мысли, что ArrayList в Java это больше список нежели массив…