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:

Java Program to Implement Self Balancing Binary Search Tree
Request a Delivery / Read Receipt in Javamail
Java Program to Implement Skip List
Guide to Apache Commons CircularFifoQueue
A Guide to Java 9 Modularity
Chương trình Java đầu tiên
Extra Login Fields with Spring Security
Java Program to Implement ConcurrentSkipListMap API
“Stream has already been operated upon or closed” Exception in Java
Guide to java.util.Formatter
Converting Between a List and a Set in Java
Spring Security OAuth Login with WebFlux
Java Program to Implement DelayQueue API
Hướng dẫn Java Design Pattern – Dependency Injection
Zipping Collections in Java
Java Program to Apply Above-Below-on Test to Find the Position of a Point with respect to a Line
How to Get All Dates Between Two Dates?
Query Entities by Dates and Times with Spring Data JPA
Spring Boot - Batch Service
Registration with Spring Security – Password Encoding
REST Web service: Tạo ứng dụng Java RESTful Client với Jersey Client 2.x
Java CyclicBarrier vs CountDownLatch
Lớp lồng nhau trong java (Java inner class)
Converting a Stack Trace to a String in Java
Java Program to Decode a Message Encoded Using Playfair Cipher
Quick Guide to Spring MVC with Velocity
Dockerizing a Spring Boot Application
Java Program to Find k Numbers Closest to Median of S, Where S is a Set of n Numbers
Java Program to Use Boruvka’s Algorithm to Find the Minimum Spanning Tree
Java Program to Implement Sorted Array
Câu lệnh điều khiển vòng lặp trong Java (break, continue)
Java Program to Implement Solovay Strassen Primality Test Algorithm