List Interface and ArrayList in Java - Quiz
Total: 5 questions
1. What is the difference between the capacity and the size of an ArrayList?
What is the difference between the capacity and the size of an ArrayList?
Capacity is the length of the internal Object[] array, while size() is the number of elements actually added. Since Java 8, new ArrayList<>() starts with an empty array and allocates 10 slots on the first add(); when the array is full, it is replaced with one about 1.5 times larger (10, 15, 22, 33...).
Capacity does not make indexes usable: after new ArrayList<>(10) the size is 0, and list.set(0, "Java") or list.get(0) throws IndexOutOfBoundsException. You can pre-size the array with the constructor or ensureCapacity(n) and release unused slots with trimToSize(); both methods exist only on the ArrayList class.
2. What List implementations does Java have, and which one should you choose by default?
What List implementations does Java have, and which one should you choose by default?
The main implementations are ArrayList (a resizable array, get(i) in O(1)), LinkedList (a doubly linked list, index access in O(n)), the legacy Vector (and Stack) with synchronized methods, the thread-safe CopyOnWriteArrayList that copies its array on every write, and the immutable lists from List.of() and List.copyOf(), which forbid null.
The default choice is ArrayList: it has the fastest index access and the smallest memory overhead. Inserting or removing at the start or in the middle costs O(n), because the tail of the array has to be shifted.
3. What is the difference between remove(int index) and remove(Object o) on a List<Integer>?
What is the difference between remove(int index) and remove(Object o) on a List<Integer>?
remove(int index) removes the element at a position and returns it; remove(Object o) removes the first occurrence of a value and returns true or false. When the argument is an int literal, the compiler picks remove(int) without autoboxing.
For new ArrayList<>(List.of(10, 20, 30)), remove(1) removes 20 and leaves [10, 30], while remove(10) throws IndexOutOfBoundsException. To remove the number itself, pass an object: remove(Integer.valueOf(10)).
4. What do indexOf(), lastIndexOf() and contains() return on a List, and why do your own classes need equals()?
What do indexOf(), lastIndexOf() and contains() return on a List, and why do your own classes need equals()?
indexOf(o) returns the index of the first occurrence and lastIndexOf(o) the index of the last one; both return -1 when the element is absent. contains(o) returns only true or false. All three scan the list linearly, in O(n).
Elements are compared with equals(). If your class does not override it, references are compared, and an object with the same field values will not be found. For frequent lookups where order does not matter, a HashSet is faster: its contains() is O(1) on average.
5. What does subList(from, to) return, and what is the catch?
What does subList(from, to) return, and what is the catch?
subList(from, to) returns a view, not a copy, of the elements from index from up to to - 1. Changes through the view show up in the original list and the other way round: list.subList(1, 3).clear() removes that range from the list itself.
After a structural change of the original list (add(), remove()), using the old view throws ConcurrentModificationException, and from > to throws IllegalArgumentException. To get an independent part, copy it: new ArrayList<>(list.subList(1, 3)).