Java Collections – ArrayList

How to properly create and use an ArrayList including adding, retrieving and modifying items.

Check out the previous parts of this Java Collections Guide: Introduction, Part 1 – Collection and Part 2 – Sets.

1. Introduction

The ArrayList is one of the most widely used classes in the Java Collections Framework (if not the entire JDK; that position probably belongs to String). It provides a simple array-like storage of items with dynamically adjusting capacity. In this article, we present some usage patterns of the List and ArrayList.

Since we have covered the methods applicable to Iterable and Collection in a previous guide, we focus on the methods specific to an ArrayList here.

ArrayList Class Hierarchy

2. Adding Items

Several ways to add items to a List.

2.1. Add at the end

Add items to the end of the List with add(). Simple usage needs no further explanation.

List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.forEach(System.out::println);

// prints:
A
B

2.2. Add at an index

Add items at a particular position with add(int,E). Note that items appearing at and after the specified index are pushed back.

List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add(0, "C");
names.add(0, "D");
names.forEach(System.out::println);

// prints:
D
C
A
B

2.3. Add a Collection

And here is how you can add a collection of items at a particular position.

List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
names.addAll(1, Arrays.asList("D",
			      "E",
			      "F"));
names.forEach(System.out::println);

// prints:
A
D
E
F
B
C

2.4. Add with an Iterator

Retrieve an iterator pointing at a specific position and add items using the iterator.

List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
ListIterator<String> li = names.listIterator(1);
li.add("D");
li.add("E");
names.forEach(System.out::println);

// prints:
A
D
E
B
C

3. Retrieving Items

3.1. Get Item at an Index

The most basic item retrieval for a List is the get(int).

List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
names.add("D");
names.add("E");
System.out.println(names.get(1));
System.out.println(names.get(4));

// prints:
B
E

3.2. Process Items Starting at an Index

What if you want to retrieve a bunch of items starting from a given index? You use the listIterator(int) method for an iterator and forEachRemaining() to process the items.

List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
names.add("D");
names.add("E");
ListIterator<String> li = names.listIterator(2);
li.forEachRemaining(System.out::println);

// prints:
C
D
E

3.3. Process Items Backward with an Iterator

If you want to process all items before a specific index, use a normal iterator loop to move backwards through the list:

List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
names.add("D");
names.add("E");
ListIterator<String> li = names.listIterator(2);
while (li.hasPrevious()) System.out.println(li.previous());

// prints
B
A

3.4. Retrieve a Part of the List

You can retrieve a part of the list between specified indices and process that list.

List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
names.add("D");
names.add("E");
names.subList(1, 3).forEach(System.out::println);

// prints:
B
C

4. Modifying Items

4.1. Set Item at Index

To modify an item at a particular index, use set(int,E).

List<String> names = new ArrayList<>();
names.addAll(Arrays.asList("A", "B", "C", "D", "E", "F"));
names.set(2, "A");
names.forEach(System.out::println);

// prints
A
B
A
D
E
F

4.2. Modify Items using Iterator

Another method is to use a ListIterator. The following code finds a particular item, creates a list iterator starting at that position and updates all subsequent elements.

List<String> names = new ArrayList<>();
names.addAll(Arrays.asList("A", "B", "C", "D", "E", "F"));
int pos = names.indexOf("C");
ListIterator<String> li = names.listIterator(pos);
while (li.hasNext()) {
    String str = li.next();
    li.set(str.toLowerCase());
}
names.forEach(System.out::println);

// prints
A
B
c
d
e
f

5. Search for Item

Searching for an item is pretty easy with indexOf(E). You saw an example of its usage above.

The analogous method lastIndexOf() searches for an item from the end of the List. Here is an example of its usage.

List<String> names = new ArrayList<>();
names.addAll(Arrays.asList("A", "B", "C", "C", "E", "F"));
int pos = names.lastIndexOf("C");
names.set(pos, "CC");
names.forEach(System.out::println);

// prints
A
B
C
CC
E
F

6. Sorting

Sort a list using the sort() method. It does take a comparator argument which can be null, in which case a natural ordering of the items is used.

Random random = new Random();
List<Integer> list = random.ints(10, 0, 20).boxed().collect(Collectors.toList());
System.out.println(list);
list.sort(null);
System.out.println(list);

// prints:
[11, 19, 13, 2, 10, 7, 18, 5, 18, 14]
[2, 5, 7, 10, 11, 13, 14, 18, 18, 19]

Let us supply a comparator lambda to the sort method to reverse the order.

Random random = new Random();
List<Integer> list = random.ints(10, 0, 20).boxed().collect(Collectors.toList());
System.out.println(list);
list.sort((x, y) -> Integer.compare(y, x));
System.out.println(list);

// prints:
[17, 1, 14, 18, 3, 13, 6, 6, 6, 15]
[18, 17, 15, 14, 13, 6, 6, 6, 3, 1]

Summary

While methods of the Collection are applicable to all collection classes, the methods discussed here are specific to these classes.

See Also