775

How can I get the last value of an ArrayList?

Sambhav Khandelwal
  • 3,585
  • 2
  • 7
  • 38
Jessy
  • 15,321
  • 31
  • 83
  • 100
  • 214
    I upvoted this question, because I was wondering why there's no such a method like: getLastItem() and came to see if there was an answer. list.size() - 1 is not pretty. – Nuno Gonçalves Nov 23 '12 at 17:31
  • 2
    @NunoGonçalves You can always subclass it! – Tim Jul 26 '13 at 19:19
  • 13
    You could always use a LinkedList which has the method `getLast()` – ssedano Apr 25 '14 at 22:56
  • 6
    Linked listing it adds a whole heap of overhead. Use Guava as shown below : lastElement = Iterables.getLast(iterableList); OR simply index a get() call with size() - 1. Its not that ugly compared to using a linked list when its not required. Usual caveats apply regarding exception conditions - see the ArrayList javadoc. – RichieHH May 23 '14 at 11:43
  • 17
    Using list.size() -1 is not pretty, but using a 3rd party API just for this is worse – Javo Jul 19 '17 at 14:52
  • 1
    @Javo I agree with you about the 3dr party if it's a one time situation, but let's just be honest: there are plenty of situations where you'll find useful to have a 3rd party API like Guava or Apache Commons in your application. Beginners might not know them or what they can do, or might not think about them when they're looking for answers. It is likely that you will use these APIs more than once. Consequently I find it interesting to have both vanilla java and APIs solutions, so that people can discover those APIs if they want to. – Carrm Jan 03 '19 at 15:14
  • I favorited this question just to remember how crazy the world of programming has become... – Matthieu Jul 08 '19 at 12:22
  • I don't understand what's not pretty about list.size()-1, it's very clear what it means. Or would you prefer the perl notation: $list[$#list] would that be better? – soger Oct 26 '20 at 12:30
  • 3
    @soger No, but "it could be worse" is not a satisfactory reason to not have a readable method like `getLastElement()` be part of the java.util.List API. – Alexander Terp Apr 09 '21 at 05:35
  • 1
    There is a [JEP 431](https://openjdk.org/jeps/431) that will introduce `SequencedCollection` to Java. There will be methods such as `getFirst()`, `getLast()`, `addFirst()` and so forth. – ZhekaKozlov Nov 04 '22 at 13:23
  • 1
    @ZhekaKozlov I've added an answer that uses this: https://stackoverflow.com/a/76470369/1108305. – M. Justin Jun 14 '23 at 05:30

24 Answers24

853

The following is part of the List interface (which ArrayList implements):

E e = list.get(list.size() - 1);

E is the element type. If the list is empty, get throws an IndexOutOfBoundsException. You can find the whole API documentation here.

Jarvis
  • 8,494
  • 3
  • 27
  • 58
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 7
    Will this cause an iteration of the list? That doesnt seem very efficient to me. I come from C++, where there are actual front() and back() methods on the list object, that are internally implemented with head and tail references. Is there a similar mechanism in Java? – Brady Oct 13 '14 at 09:18
  • 37
    Won't work. what if the list is empty, list.size() will return 0. and you'll end up with list.get(-1); – frankelot Jan 21 '15 at 19:36
  • 27
    @feresr huh. He wants to get the last value in the list. Of course that implies that size() is > 0. That would be true for any sort of implementation. Reading through to the end would have saved the time you needed to write your comment and my time for answering :) My answer says at the end *"If the list is empty, get throws an IndexOutOfBoundsException"* – Johannes Schaub - litb Jan 22 '15 at 23:20
  • 21
    @Brady it won't cause an O(n) iteration for an ArrayList, because as you can guess, it's backed by an array. So a simple get() just results in a constant-time retrieve from an array. (JDK source confirms this) For other list implementations, this isn't guaranteed, so for example, LinkedList has a getLast() method which is constant-time. – Peter Mar 19 '15 at 19:58
  • 1
    Isn't there a more elegant way to do this? When I used to code mainly in C/C++ I remember being able to use `list.back()` or similar... would be a nice feature in Java. –  Jul 29 '15 at 12:53
  • 1
    @poirot, Implementation of a List.back() method would likely do exactly what is shown here anyway. – sherrellbc Mar 23 '16 at 04:43
  • 3
    @sherrellbc it would do exactly the same. If Java had this function it would save me time typing. –  Mar 23 '16 at 21:27
  • 19
    I can't understand why they decided to implement a simple `lastElement()` method for their `Vector` but not for `ArrayList`. What's up with that inconsistency? – Stefan Dimitrov Sep 07 '16 at 09:54
  • 2
    I googled this because my brain says "there must be an easier way". Java is starting to feel so low-level. – Fletch Aug 21 '17 at 06:25
  • 2
    Does `list.get(list.size()--)` work or it doesn't work? –  Dec 19 '17 at 06:48
  • Probably stupid, but does `List::get` guarantee sequential returns? I.e. is `list.get(0);` guaranteed to be the _first_ element (if one exists, blah blah), `list.get(1)` the second, etc.? Or are `List` implementations free to index as they choose as long as their `Iterator` functions in the appropriate order? – BeUndead Oct 10 '18 at 15:27
  • 1
    @user2478398 It does guaRantee sequential returns. – Dorian Gray Oct 19 '19 at 21:19
250

There isn't an elegant way in vanilla Java.

Google Guava

The Google Guava library is great - check out their Iterables class. This method will throw a NoSuchElementException if the list is empty, as opposed to an IndexOutOfBoundsException, as with the typical size()-1 approach - I find a NoSuchElementException much nicer, or the ability to specify a default:

lastElement = Iterables.getLast(iterableList);

You can also provide a default value if the list is empty, instead of an exception:

lastElement = Iterables.getLast(iterableList, null);

or, if you're using Options:

lastElementRaw = Iterables.getLast(iterableList, null);
lastElement = (lastElementRaw == null) ? Option.none() : Option.some(lastElementRaw);
Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137
Antony Stubbs
  • 13,161
  • 5
  • 35
  • 39
  • 3
    Do you know if this this method do a linear walk through the list to find the last element? – BillMan Feb 20 '13 at 15:51
  • 6
    @BillMan In the case of HashSet yes, in the case of ArrayList no. – Simon Aug 19 '13 at 12:50
  • 6
    You should add that `Iterables.getLast` check whether `RandomAccess` is implemented and therefore if it is accesses the item in O(1). – Kalle Richter Jun 22 '17 at 23:23
  • 2
    Instead of `Option`, you can use the native Java `Optional`. It will also be a bit cleaner: `lastElement = Optional.ofNullable(lastElementRaw);`. – Little Helper May 07 '19 at 08:15
201

this should do it:

if (arrayList != null && !arrayList.isEmpty()) {
  T item = arrayList.get(arrayList.size()-1);
}
Christian
  • 22,585
  • 9
  • 80
  • 106
Henrik Paul
  • 66,919
  • 31
  • 85
  • 96
32

I use micro-util class for getting last (and first) element of list:

public final class Lists {

    private Lists() {
    }

    public static <T> T getFirst(List<T> list) {
        return list != null && !list.isEmpty() ? list.get(0) : null;
    }

    public static <T> T getLast(List<T> list) {
        return list != null && !list.isEmpty() ? list.get(list.size() - 1) : null;
    }
}

Slightly more flexible:

import java.util.List;

/**
 * Convenience class that provides a clearer API for obtaining list elements.
 */
public final class Lists {

  private Lists() {
  }

  /**
   * Returns the first item in the given list, or null if not found.
   *
   * @param <T> The generic list type.
   * @param list The list that may have a first item.
   *
   * @return null if the list is null or there is no first item.
   */
  public static <T> T getFirst( final List<T> list ) {
    return getFirst( list, null );
  }

  /**
   * Returns the last item in the given list, or null if not found.
   *
   * @param <T> The generic list type.
   * @param list The list that may have a last item.
   *
   * @return null if the list is null or there is no last item.
   */
  public static <T> T getLast( final List<T> list ) {
    return getLast( list, null );
  }

  /**
   * Returns the first item in the given list, or t if not found.
   *
   * @param <T> The generic list type.
   * @param list The list that may have a first item.
   * @param t The default return value.
   *
   * @return null if the list is null or there is no first item.
   */
  public static <T> T getFirst( final List<T> list, final T t ) {
    return isEmpty( list ) ? t : list.get( 0 );
  }

  /**
   * Returns the last item in the given list, or t if not found.
   *
   * @param <T> The generic list type.
   * @param list The list that may have a last item.
   * @param t The default return value.
   *
   * @return null if the list is null or there is no last item.
   */
  public static <T> T getLast( final List<T> list, final T t ) {
    return isEmpty( list ) ? t : list.get( list.size() - 1 );
  }

  /**
   * Returns true if the given list is null or empty.
   *
   * @param <T> The generic list type.
   * @param list The list that has a last item.
   *
   * @return true The list is empty.
   */
  public static <T> boolean isEmpty( final List<T> list ) {
    return list == null || list.isEmpty();
  }
}
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
user11153
  • 8,536
  • 5
  • 47
  • 50
  • 12
    Just use guava. Don't re-invent – Ali Nov 04 '16 at 18:49
  • 25
    @ClickUpvote Using Guava for just one tiny method is in many cases an overkill. My answer is for people looking for _vanilla Java solution_. If you are already using Guava in your project, see other answer for Guava-based solution. – user11153 Nov 04 '16 at 18:54
  • 6
    If you *don't* use guava, you end up writing lots of utility classes like this one. – Ali Nov 05 '16 at 15:02
  • 11
    Sometimes getting permission to add a third-party library can be a lot more involved than adding a single native Java class. For example, government contracts where they limit and screen third-party libraries. – Dave Jarvis Mar 31 '17 at 18:09
  • 2
    `isEmpty` doesn't check whether the list is empty and should thus be `isNullOrEmpty` and that's not part of the question - either you try to enhance the set of answers or you provide you utility classes (which are a re-invention). – Kalle Richter Jun 22 '17 at 23:25
15

The size() method returns the number of elements in the ArrayList. The index values of the elements are 0 through (size()-1), so you would use myArrayList.get(myArrayList.size()-1) to retrieve the last element.

Ken Paul
  • 5,685
  • 2
  • 30
  • 33
8

There is no elegant way of getting the last element of a list in Java (compared to e.g. items[-1] in Python).

You have to use list.get(list.size()-1).

When working with lists obtained by complicated method calls, the workaround lies in temporary variable:

List<E> list = someObject.someMethod(someArgument, anotherObject.anotherMethod());
return list.get(list.size()-1);

This is the only option to avoid ugly and often expensive or even not working version:

return someObject.someMethod(someArgument, anotherObject.anotherMethod()).get(
    someObject.someMethod(someArgument, anotherObject.anotherMethod()).size() - 1
);

It would be nice if fix for this design flaw was introduced to Java API.

Tregoreg
  • 18,872
  • 15
  • 48
  • 69
  • I do not see a "design flaw" here, what you bring up is a rare use case that's not worth to be added to the `List` interface. Why would you want to call a method returning a List, if you're only interested in the last element? I do not remember I have seen that at all before. – Dorian Gray Oct 20 '19 at 09:44
  • 3
    @DorianGray Reading last element from a list is a pretty common operation and `list.get(list.size()-1)` is the minimal example showing the issue. I agree that the "advanced" examples may be controversial and possibly an edge case, I just wanted to show how the issue can further propagate. Let's assume that the class of `someObject` is foreign, coming from external library. – Tregoreg Oct 20 '19 at 14:07
  • I do not see where this is pretty common, and if it is, you better use `ArrayDeque` instead. – Dorian Gray Oct 20 '19 at 16:39
  • 1
    @DorianGray This question has a lot of upvotes and views, so there is a lot of people interested in getting the last value of an `ArrayList`. – Tregoreg Oct 20 '19 at 16:51
7

Using lambdas:

Function<ArrayList<T>, T> getLast = a -> a.get(a.size() - 1);
5

If you can, swap out the ArrayList for an ArrayDeque, which has convenient methods like removeLast.

John Glassmyer
  • 301
  • 3
  • 10
  • 1
    This means at least linear cost in comparison to constant cost for direct access, but worth mentioning. – Kalle Richter Jun 22 '17 at 23:28
  • @KarlRichter Yes. This corresponds with the absence of methods like get(int) in ArrayDeque's interface. This is what I meant to suggest by "If you can"; if the list is not being accessed by index, then perhaps it doesn't need to be a List. – John Glassmyer Jul 13 '17 at 05:09
5

If you use a LinkedList instead , you can access the first element and the last one with just getFirst() and getLast() (if you want a cleaner way than size() -1 and get(0))

Implementation

Declare a LinkedList

LinkedList<Object> mLinkedList = new LinkedList<>();

Then this are the methods you can use to get what you want, in this case we are talking about FIRST and LAST element of a list

/**
     * Returns the first element in this list.
     *
     * @return the first element in this list
     * @throws NoSuchElementException if this list is empty
     */
    public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }

    /**
     * Returns the last element in this list.
     *
     * @return the last element in this list
     * @throws NoSuchElementException if this list is empty
     */
    public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }

    /**
     * Removes and returns the first element from this list.
     *
     * @return the first element from this list
     * @throws NoSuchElementException if this list is empty
     */
    public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }

    /**
     * Removes and returns the last element from this list.
     *
     * @return the last element from this list
     * @throws NoSuchElementException if this list is empty
     */
    public E removeLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }

    /**
     * Inserts the specified element at the beginning of this list.
     *
     * @param e the element to add
     */
    public void addFirst(E e) {
        linkFirst(e);
    }

    /**
     * Appends the specified element to the end of this list.
     *
     * <p>This method is equivalent to {@link #add}.
     *
     * @param e the element to add
     */
    public void addLast(E e) {
        linkLast(e);
    }

So , then you can use

mLinkedList.getLast(); 

to get the last element of the list.

Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
5

As stated in the solution, if the List is empty then an IndexOutOfBoundsException is thrown. A better solution is to use the Optional type:

public class ListUtils {
    public static <T> Optional<T> last(List<T> list) {
        return list.isEmpty() ? Optional.empty() : Optional.of(list.get(list.size() - 1));
    }
}

As you'd expect, the last element of the list is returned as an Optional:

var list = List.of(10, 20, 30);
assert ListUtils.last(list).orElse(-1) == 30;

It also deals gracefully with empty lists as well:

var emptyList = List.<Integer>of();
assert ListUtils.last(emptyList).orElse(-1) == -1;
Colin Breame
  • 1,367
  • 2
  • 15
  • 18
4

In case you have a Spring project, you can also use the CollectionUtils.lastElement from Spring (javadoc), so you don't need to add an extra dependency like Google Guava.

It is null-safe so if you pass null, you will simply receive null in return. Be careful when handling the response though.

Here are somes unit test to demonstrate them:

@Test
void lastElementOfList() {
    var names = List.of("John", "Jane");

    var lastName = CollectionUtils.lastElement(names);

    then(lastName)
        .as("Expected Jane to be the last name in the list")
        .isEqualTo("Jane");
}

@Test
void lastElementOfSet() {
    var names = new TreeSet<>(Set.of("Jane", "John", "James"));

    var lastName = CollectionUtils.lastElement(names);

    then(lastName)
        .as("Expected John to be the last name in the list")
        .isEqualTo("John");
}

Note: org.assertj.core.api.BDDAssertions#then(java.lang.String) is used for assertions.

Jacob van Lingen
  • 8,989
  • 7
  • 48
  • 78
BitfulByte
  • 4,117
  • 1
  • 30
  • 40
4

A one liner that takes into account empty lists would be:

T lastItem = list.size() == 0 ? null : list.get(list.size() - 1);

Or if you don't like null values (and performance isn't an issue):

Optional<T> lastItem = list.stream().reduce((first, second) -> second);
Craigo
  • 3,384
  • 30
  • 22
3

In the upcoming Java 21 the new getLast method can be used, which will return the last item if the list is nonempty, else it will throw a NoSuchElementException.

list.getLast();
M. Justin
  • 14,487
  • 7
  • 91
  • 130
1

Since the indexing in ArrayList starts from 0 and ends one place before the actual size hence the correct statement to return the last arraylist element would be:

int last = mylist.get(mylist.size()-1);

For example:

if size of array list is 5, then size-1 = 4 would return the last array element.

1

guava provides another way to obtain the last element from a List:

last = Lists.reverse(list).get(0)

if the provided list is empty it throws an IndexOutOfBoundsException

pero_hero
  • 2,881
  • 3
  • 10
  • 24
-1

This worked for me.

private ArrayList<String> meals;
public String take(){
  return meals.remove(meals.size()-1);
}
Med Sep
  • 346
  • 1
  • 6
-2

The last item in the list is list.size() - 1. The collection is backed by an array and arrays start at index 0.

So element 1 in the list is at index 0 in the array

Element 2 in the list is at index 1 in the array

Element 3 in the list is at index 2 in the array

and so on..

MircoProgram
  • 295
  • 1
  • 20
-3

If you modify your list, then use listIterator() and iterate from last index (that is size()-1 respectively). If you fail again, check your list structure.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
dae
  • 1
-4

How about this.. Somewhere in your class...

List<E> list = new ArrayList<E>();
private int i = -1;
    public void addObjToList(E elt){
        i++;
        list.add(elt);
    }


    public E getObjFromList(){
        if(i == -1){ 
            //If list is empty handle the way you would like to... I am returning a null object
            return null; // or throw an exception
        }

        E object = list.get(i);
        list.remove(i); //Optional - makes list work like a stack
        i--;            //Optional - makes list work like a stack
        return object;
    }
rokrfellr
  • 9
  • 2
-4

All you need to do is use size() to get the last value of the Arraylist. For ex. if you ArrayList of integers, then to get last value you will have to

int lastValue = arrList.get(arrList.size()-1);

Remember, elements in an Arraylist can be accessed using index values. Therefore, ArrayLists are generally used to search items.

Undo
  • 25,519
  • 37
  • 106
  • 129
user4660857
  • 773
  • 6
  • 6
-4

arrays store their size in a local variable called 'length'. Given an array named "a" you could use the following to reference the last index without knowing the index value

a[a.length-1]

to assign a value of 5 to this last index you would use:

a[a.length-1]=5;

-5

To Get the last value of arraylist in JavaScript :

var yourlist = ["1","2","3"];
var lastvalue = yourlist[yourlist.length -1];

It gives the output as 3 .

-6

Alternative using the Stream API:

list.stream().reduce((first, second) -> second)

Results in an Optional of the last element.

Terran
  • 1,091
  • 18
  • 29
-10

In Kotlin, you can use the method last:

val lastItem = list.last()
Ollie
  • 1,641
  • 1
  • 13
  • 31
  • 19
    This is java however – Jachdich Oct 03 '19 at 10:19
  • 5
    One of the ideas behind creating Kotlin was to cover the little uncomfortable sides of Java. So I think it makes sense to recommend considering Kotlin, at least for the parts of the application that do data analasys. – Eerik Sven Puudist Feb 08 '20 at 21:24