Check if ArrayList Is Empty in Java: isEmpty() vs size()

Check if ArrayList is empty in Java with isEmpty() or size(), handle null lists with Commons and Spring, and empty a list with clear() vs removeAll().

Table of isEmpty, size and null-safe checks for a null list, an empty list and a list with one item

An ArrayList is empty when it holds no elements, and we check that with list.isEmpty(), which returns true for an empty list and false otherwise. The expression list.size() == 0 gives the same answer, but isEmpty() states the intent and is the recommended form.

An empty check guards the code that reads the first element, sends a batch or renders a result table, so an empty search result shows a friendly message instead of an exception. The opposite job, emptying a list, belongs to clear(), which we compare with removeAll() and with creating a new list.

The following example checks a shopping basket before and after adding an item, and empties it again.

List<String> basket = new ArrayList<>();
boolean empty = basket.isEmpty();                        // true
basket.add("milk");
boolean stillEmpty = basket.isEmpty();                   // false
boolean noItems = basket.size() == 0;                    // false
boolean nullOrEmpty = basket == null || basket.isEmpty();   // false
basket.clear();
boolean emptyAgain = basket.isEmpty();                   // true

Notice the basket == null check on the sixth line, because isEmpty() cannot run on a null reference. We look at isEmpty() and size() first, cover null-safe checks with plain Java, Apache Commons and Spring, and finish with the right way to clear a list.

1. Checking an ArrayList With isEmpty()

The isEmpty() method takes no arguments and returns a boolean. In ArrayList, it compares the internal size field with zero, so the call costs the same for a list of 3 elements as for a list of 3 million.

List<String> basket = new ArrayList<>(List.of("milk", "eggs"));
boolean hasItems = !basket.isEmpty();                    // true
List<String> none = List.of();
boolean nothing = none.isEmpty();                        // true

The main reason for the check is the first-element access. On an empty list, get(0) throws IndexOutOfBoundsException, and the Java 21 method getFirst() throws NoSuchElementException. Both are bugs that an isEmpty() guard or a stream with findFirst() avoids.

List<String> basket = new ArrayList<>();
String first = basket.getFirst();                        // NoSuchElementException
String safe = basket.isEmpty() ? "none" : basket.getFirst();   // "none"
Optional<String> maybe = basket.stream().findFirst();    // Optional.empty

A list that contains only null elements is not empty. For example, Arrays.asList(null, null) has a size of 2, so isEmpty() returns false, and we need a check such as stream().allMatch(Objects::isNull) to treat it as empty.

2. isEmpty() vs size() == 0

For an ArrayList, both checks read the same field, so neither is faster. The difference shows up in readability and in other collection types, where size() may have to count the elements.

CheckReads asCost on ArrayListCost on other collections
list.isEmpty()“is the list empty?”ConstantConstant in the common JDK collections
list.size() == 0“is the count zero?”ConstantLinear for ConcurrentLinkedQueue and ConcurrentLinkedDeque
list.size() > 0“has at least one element”ConstantSame as above

The ConcurrentLinkedQueue.size() Javadoc states that the method is not a constant-time operation, because it traverses the elements. Code that uses isEmpty() everywhere stays correct and fast when someone changes the collection type later, so we write isEmpty() and keep size() for the cases where we need the count.

3. Null-Safe Empty Checks

A List field or a method result can be null instead of empty, for example when a JSON field is missing or a legacy method returns null for “no data”. Calling isEmpty() on null throws NullPointerException, so the check must test the reference first.

Table of isEmpty, size and null-safe checks for a null list, an empty list and a list with one item
Only a null-safe check gives an answer for all three cases, a null reference, an empty list and a list with items
List<String> basket = null;
boolean bad = basket.isEmpty();                          // NullPointerException
boolean isEmptyOrNull = basket == null || basket.isEmpty();   // true
boolean viaDefault = Objects.requireNonNullElse(basket, List.<String>of()).isEmpty();   // true

The order of the two conditions matters. The || operator skips the right side when the left side is true, so isEmpty() never runs on null. For the opposite check, “has items”, we write basket != null && !basket.isEmpty().

3.1. Apache Commons and Spring Helper Methods

Projects that already use Apache Commons Collections can call CollectionUtils.isEmpty() and CollectionUtils.isNotEmpty(), which handle null for us. The examples use commons-collections4 4.5.0.

import org.apache.commons.collections4.CollectionUtils;
List<String> missing = null;
List<String> basket = new ArrayList<>(List.of("milk"));
boolean emptyMissing = CollectionUtils.isEmpty(missing); // true
boolean filled = CollectionUtils.isNotEmpty(basket);     // true

Spring Framework has a class with the same simple name, org.springframework.util.CollectionUtils, and its isEmpty() also returns true for null. The two classes cannot both be imported in one file, so we use the one our project already depends on, or write the fully qualified name for the second one.

List<String> missing = null;
boolean springEmpty = org.springframework.util.CollectionUtils.isEmpty(missing);   // true

3.2. Returning an Empty List Instead of null

The cleanest null-safe check is the one we never need, so our own methods return an empty list instead of null. The callers can loop over the result or call isEmpty() without a null test, and the code reads the same for zero, one or many results.

static List<String> findCoupons(String customer) {
    if (customer == null || customer.isBlank()) {
        return List.of();
    }
    return customer.equals("lokesh") ? List.of("SAVE10") : List.of();
}
boolean noCoupons = findCoupons("alex").isEmpty();       // true
int count = findCoupons("lokesh").size();                // 1

4. Emptying an ArrayList With clear()

The clear() method removes every element from the list in one call. It sets each used slot of the internal array to null so the garbage collector can reclaim the elements, and resets the size to 0. The list object stays the same, so every reference to it sees the empty list.

List<String> basket = new ArrayList<>(List.of("milk", "eggs", "bread"));
List<String> sameBasket = basket;
basket.clear();
int size = sameBasket.size();                            // 0
boolean empty = basket.isEmpty();                        // true

An unmodifiable list, such as one from List.of() or stream().toList(), throws UnsupportedOperationException on clear(), even when it is already empty. We copy it into a new ArrayList first if we need to change it.

List<String> fixed = List.of("milk");
fixed.clear();                                           // UnsupportedOperationException

4.1. clear() vs removeAll()

The call list.removeAll(list) also empties a list, but it does much more work. The method removeAll() removes the elements that appear in the argument, so it calls contains() on the argument for every element. When the argument is the same ArrayList, each contains() call scans the list, so emptying n elements costs about n * n / 2 comparisons, whereas clear() visits each slot once.

List<String> basket = new ArrayList<>(List.of("milk", "eggs", "bread"));
boolean changed = basket.removeAll(basket);              // true
boolean empty = basket.isEmpty();                        // true

So we use clear() to empty a list and keep removeAll() for its real job, removing a group of values such as the out-of-stock items from a basket. The article on removing elements from an ArrayList covers removeAll() and removeIf() in detail.

Way to emptySame list objectCostCapacity afterwards
list.clear()Yes, every reference sees the empty listLinearUnchanged
list.removeAll(list)YesQuadratic for an ArrayList argumentUnchanged
list = new ArrayList<>()No, other references keep the old elementsConstant, old list left to the garbage collectorDefault (10 on the first add)

4.2. clear() vs Assigning a New ArrayList

Assigning a new ArrayList to the variable does not touch the old list. Any other variable, field or caller that holds the old reference still sees all the elements, which is the right behavior when we hand a finished batch to another component and start a fresh one.

List<String> batch = new ArrayList<>(List.of("milk", "eggs"));
List<String> sent = batch;
batch = new ArrayList<>();
int sentSize = sent.size();                              // 2
boolean fresh = batch.isEmpty();                         // true

A cleared list keeps its internal array, so a list that once held a million elements still holds an array of that size. When such a list stays alive for long, we call trimToSize() after clear(), or replace the list with a new one.

5. Validating a Basket at Checkout

Say an online grocery store has a checkout endpoint. The request may arrive without a basket, with an empty basket or with items, and after a successful order the basket must be empty for the next visit.

static String checkout(List<String> basket) {
    if (basket == null || basket.isEmpty()) {
        return "Your basket is empty";
    }
    String summary = basket.size() + " items, starting with " + basket.getFirst();
    basket.clear();
    return summary;
}
List<String> basket = new ArrayList<>(List.of("milk", "eggs"));
String noBasket = checkout(null);                        // "Your basket is empty"
String placed = checkout(basket);                        // "2 items, starting with milk"
boolean resetDone = basket.isEmpty();                    // true

The method rejects both a missing and an empty basket with one condition, and it reads the first item only after the guard. The call to clear() empties the same list object the session holds, so the next page load shows an empty basket.

6. Empty ArrayList FAQs

Most questions about empty lists are about null references, speed and capacity.

6.1. Does isEmpty() throw NullPointerException?

Yes, when the list reference itself is null. The method needs an object to run on, so we check list == null first or use a null-safe helper such as CollectionUtils.isEmpty().

6.2. Is isEmpty() faster than size() == 0?

Not for ArrayList, where both read one field. For concurrent queues such as ConcurrentLinkedQueue, size() walks all elements, so isEmpty() is the safer habit.

6.3. Does clear() reduce the capacity of an ArrayList?

No. The method clear() keeps the internal array and only sets the slots to null. We call trimToSize() afterwards to shrink the array to the current size.

6.4. How do we check that a list is empty or contains only blank strings?

We combine both checks in one stream call, because allMatch() returns true for an empty stream.

List<String> notes = Arrays.asList("", " ", null);
boolean blank = notes.stream().allMatch(s -> s == null || s.isBlank());   // true

6.5. Should we return null or an empty list from a method?

We return an empty list. List.of() returns a shared unmodifiable instance, so it costs nothing, and callers can use the result without a null check, as shown in section 3.

7. Conclusion

We check an ArrayList for emptiness with isEmpty(), and add a null test in front of it only when the reference can be null. Commons Collections and Spring offer CollectionUtils.isEmpty() for that case, and returning List.of() from our own methods avoids it entirely.

To empty a list, clear() is the right call. It keeps the same list object, runs in linear time and keeps the capacity, whereas removeAll(list) does quadratic work and assigning a new list leaves the old elements visible to other references.

8. References

Happy Learning !!

Source Code on Github

Leave a Comment

  1. Don’t use size() to check whether the list is empty or not. Use isEmpty() instead — unless you like to reinvent the wheel.

Comments are closed.

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.