Guide to the Java ArrayList

1. Overview

In this article, we’re going to take a look at ArrayList class from the Java Collections Framework. We’ll discuss its properties, common use cases, as well as its advantages and disadvantages.

ArrayList resides within Java Core Libraries, so you don’t need any additional libraries. In order to use it just add the following import statement:

import java.util.ArrayList;

List represents an ordered sequence of values where some value may occur more than one time.

ArrayList is one of the List implementations built atop an array, which is able to dynamically grow and shrink as you add/remove elements. Elements could be easily accessed by their indexes starting from zero. This implementation has the following properties:

  • Random access takes O(1) time
  • Adding element takes amortized constant time O(1)
  • Inserting/Deleting takes O(n) time
  • Searching takes O(n) time for unsorted array and O(log n) for a sorted one

2. Create an ArrayList

ArrayList has several constructors and we will present them all in this section.

First, notice that ArrayList is a generic class, so you can parameterize it with any type you want and the compiler will ensure that, for example, you will not be able to put Integer values inside a collection of Strings. Also, you don’t need to cast elements when retrieving them from a collection.

Secondly, it is good practice to use generic interface List as a variable type, because it decouples it from a particular implementation.

2.1. Default No-Arg Constructor

List<String> list = new ArrayList<>();
assertTrue(list.isEmpty());

We’re simply creating an empty ArrayList instance.

2.2. Constructor Accepting Initial Capacity

List<String> list = new ArrayList<>(20);

Here you specify the initial length of an underlying array. This may help you avoid unnecessary resizing while adding new items.

2.3. Constructor Accepting Collection

Collection<Integer> number 
  = IntStream.range(0, 10).boxed().collect(toSet());

List<Integer> list = new ArrayList<>(numbers);
assertEquals(10, list.size());
assertTrue(numbers.containsAll(list));

Notice, that element of the Collection instance are used for populating the underlying array.

3. Add Elements to the ArrayList

You may insert an element either at the end or at the specific position:

List<Long> list = new ArrayList<>();

list.add(1L);
list.add(2L);
list.add(1, 3L);

assertThat(Arrays.asList(1L, 3L, 2L), equalTo(list));

You may also insert a collection or several elements at once:

List<Long> list = new ArrayList<>(Arrays.asList(1L, 2L, 3L));
LongStream.range(4, 10).boxed()
  .collect(collectingAndThen(toCollection(ArrayList::new), ys -> list.addAll(0, ys)));
assertThat(Arrays.asList(4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L), equalTo(list));

4. Iterate Over the ArrayList

There are two types of iterators available: Iterator and ListIterator.

While the former gives you an opportunity to traverse the list in one direction, the latter allows you to traverse it in both directions.

Here we will show you only the ListIterator:

List<Integer> list = new ArrayList<>(
  IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new))
);
ListIterator<Integer> it = list.listIterator(list.size());
List<Integer> result = new ArrayList<>(list.size());
while (it.hasPrevious()) {
    result.add(it.previous());
}

Collections.reverse(list);
assertThat(result, equalTo(list));

You may also search, add or remove elements using iterators.

5. Search the ArrayList

We will demonstrate how searching works using a collection:

List<String> list = LongStream.range(0, 16)
  .boxed()
  .map(Long::toHexString)
  .collect(toCollection(ArrayList::new));
List<String> stringsToSearch = new ArrayList<>(list);
stringsToSearch.addAll(list);

5.1. Searching an Unsorted List

In order to find an element you may use indexOf() or lastIndexOf() methods. They both accept an object and return int value:

assertEquals(10, stringsToSearch.indexOf("a"));
assertEquals(26, stringsToSearch.lastIndexOf("a"));

If you want to find all elements satisfying a predicate, you may filter collection using Java 8 Stream API using Predicate like this:

Set<String> matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9"));

List<String> result = stringsToSearch
  .stream()
  .filter(matchingStrings::contains)
  .collect(toCollection(ArrayList::new));

assertEquals(6, result.size());

It is also possible to use a for loop or an iterator:

Iterator<String> it = stringsToSearch.iterator();
Set<String> matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9"));

List<String> result = new ArrayList<>();
while (it.hasNext()) {
    String s = it.next();
    if (matchingStrings.contains(s)) {
        result.add(s);
    }
}

5.2. Searching a Sorted List

If you have a sorted array, then you may use a binary search algorithm which works faster than linear search:

List<String> copy = new ArrayList<>(stringsToSearch);
Collections.sort(copy);
int index = Collections.binarySearch(copy, "f");
assertThat(index, not(equalTo(-1)));

Notice that if an element is not found then -1 will be returned.

6. Remove Elements from the ArrayList

In order to remove an element, you should find its index and only then perform the removal via remove() method. An overloaded version of this method, that accepts an object, searches for it and performs removal of the first occurrence of an equal element:

List<Integer> list = new ArrayList<>(
  IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new))
);
Collections.reverse(list);

list.remove(0);
assertThat(list.get(0), equalTo(8));

list.remove(Integer.valueOf(0));
assertFalse(list.contains(0));

But be careful when working with boxed types such as Integer. In order to remove a particular element, you should first box int value or otherwise, an element will be removed by its index.

You may as well use the aforementioned Stream API for removing several items, but we won’t show it here. For this purpose we will use an iterator:

Set<String> matchingStrings
 = HashSet<>(Arrays.asList("a", "b", "c", "d", "e", "f"));

Iterator<String> it = stringsToSearch.iterator();
while (it.hasNext()) {
    if (matchingStrings.contains(it.next())) {
        it.remove();
    }
}

7. Summary

In this quick article, we had a look at the ArrayList in Java.

We showed how to create an ArrayList instance, how to add, find or remove elements using different approaches.

As usual, you can find all the code samples over on GitHub.

Related posts:

Convert a Map to an Array, List or Set in Java
Java Program to Print only Odd Numbered Levels of a Tree
Java Program to Generate Random Numbers Using Middle Square Method
TreeSet và sử dụng Comparable, Comparator trong java
Converting String to Stream of chars
Arrays.asList vs new ArrayList(Arrays.asList())
Guide to java.util.concurrent.Future
Collection trong java
Spring REST API with Protocol Buffers
Tìm hiểu về Web Service
Jackson – JsonMappingException (No serializer found for class)
CharSequence vs. String in Java
Java Program to Convert a Decimal Number to Binary Number using Stacks
Java Stream Filter with Lambda Expression
Custom Exception trong Java
JUnit 5 @Test Annotation
Java Program to Implement the Vigenere Cypher
Spring Boot - Admin Client
Java Program to Implement Quick Sort with Given Complexity Constraint
LIKE Queries in Spring JPA Repositories
Java Program to Perform Addition Operation Using Bitwise Operators
Java Program to Implement Hamiltonian Cycle Algorithm
Tránh lỗi NullPointerException trong Java như thế nào?
Spring Boot - Google OAuth2 Sign-In
Allow user:password in URL
Java Program to Check whether Graph is a Bipartite using 2 Color Algorithm
Java Program to Perform Insertion in a 2 Dimension K-D Tree
MyBatis with Spring
Một số từ khóa trong Java
Hướng dẫn Java Design Pattern – Mediator
Java Program to Check Whether a Weak Link i.e. Articulation Vertex Exists in a Graph
Giới thiệu Java Service Provider Interface (SPI) – Tạo các ứng dụng Java dễ mở rộng