Java: A Java list `tail` function (for ArrayList, LinkedList, etc.)

As a brief note today, I was working on a Java/Android application recently, and I needed a “tail” function when I was working on a Java list. What I mean by that is that Scala has a tail function that returns all elements of the list except for the head element, like this:

scala> val x = List(1,2,3,4)
x: List[Int] = List(1, 2, 3, 4)

scala> x.tail
res1: List[Int] = List(2, 3, 4)  //head element removed

and I wanted the same thing in Java.

A Java list `tail` function

The short answer is that Java 6/7/8 doesn’t have a list tail method, so I wrote my own tail function to work on List, ArrayList, LinkedList, etc:

/**
 * WARNING/TODO: this method doesn’t check the list size, so you better
 * be sure it contains at least one element.
 */
public static <T> List<T> tail(List<T> xs)
throws IndexOutOfBoundsException, IllegalArgumentException {
    return xs.subList(1, xs.size());
}

If the generics in that code make your eyes water, here’s a non-generic version of that function that works on a list of integers:

public static List<Integer> tail(List<Integer> xs)
throws IndexOutOfBoundsException, IllegalArgumentException {
    return xs.subList(1, xs.size());
}

I put that method in a class named ListUtils that has a bunch of other list utility functions that I like/need.

As the comment on the tail function implies, this is a potentially dangerous method. subList specifically can throw these exceptions:

  • IndexOutOfBoundsException
  • IllegalArgumentException

See my Java List subList examples for a little more information on the subList method. You might want to handle a null list of empty list in your own code, but when I thought, “What is the tail of an empty list,” I thought the answer to that question was undefined; returning an empty list is not accurate, so I let subList explode.

A `tail` function example

Here’s an example of how I use this tail function:

import static com.alvinalexander.utils.ListUtils.tail;

// later ...

if (penalty == 1) {
    return tail(listOfPossiblePlayResults);  // rm the head element
}

In that example, this code:

return tail(listOfPossiblePlayResults)

returns a new list with the head element of the list removed if the penalty is 1.

More `tail` documentation

I’m just throwing this tail function out here quickly today, but if you want to know more about how it works, here’s some example code that helps to demonstrate how it works (and fails) with several different use cases:

import java.util.*;

public class TailFunction {

    public static void main(String[] args) {

        List<String> x = new ArrayList<>();
        x.add("a");
        x.add("b");
        x.add("c");
        System.out.println(tail(x));  // [b,c]

        List<String> y = new ArrayList<>();
        y.add("a");
        System.out.println(tail(y));  // []

        // an exmpty list throws an exception
        List<String> z = new ArrayList<>();
        System.out.println(tail(z));  // IllegalArgumentException: fromIndex(1) > toIndex(0)

    }

    public static <T> List<T> tail(List<T> xs)
    throws IndexOutOfBoundsException, IllegalArgumentException {
        return xs.subList(1, xs.size());
    }

}

A Java List `head` function

As a brief related note, I haven’t tested this code, but a Java List head function should look like this:

public static <T> List<T> head(List<T> xs)
throws IndexOutOfBoundsException, IllegalArgumentException {
    return xs.subList(0, 1);
}

I know this might not seem like much to Java OOP developers, but when you use head/tail functions like this all the time in languages like Scala, you sure do miss them when you work with Java.

Summary

In summary, if you need a tail function that works on a Java list — such as an ArrayList or LinkedList — I hope this example and source code is helpful. Also note that if you don’t want to have to create your own “list utilities” library, there are other libraries in existence, such as the Apache Commons library.

Add new comment

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.