tom
tom

Reputation: 14513

Get the last element of a Java collection

I have a collection, and I want to get the last element of it. What's the most straighforward and fast way to do so?

One solution is to first toArray(), and then return the last element of the array. Are there any other better ones?

Upvotes: 67

Views: 181861

Answers (10)

kukudas
kukudas

Reputation: 4934

Well one solution could be to convert the collection to a List (maybe like this: new ArrayList(coll)) and then get the last item using List.get(int index):

list.get(list.size()-1)

Upvotes: 10

M. Justin
M. Justin

Reputation: 21132

For an arbitrary non-empty collection, the following gets the last element by streaming over the collection, skipping everything but the last element:

c.stream().skip(c.size() - 1).findFirst().orElseThrow()

If the collection is of a type that provides a built-in mechanism to efficiently get the last element (in particular, the SequencedCollection types — List, SortedSet, LinkedHashSet, etc.), this will generally be much less efficient than using the mechanism provided by that type. If you don't know the Collection type ahead of time, but want to optimize for this very common case, you could do so:

Collection<Integer> c = getCollection();

String last = c instanceof SequencedCollection<Integer> s 
        ? s.getLast()
        : c.stream().skip(c.size() - 1).findFirst()
                .orElseThrow(NoSuchElementException::new);

Upvotes: 2

Jack Edmonds
Jack Edmonds

Reputation: 33171

A Collection is not a necessarily ordered set of elements so there may not be a concept of the "last" element. If you want something that's ordered, you can use a SortedSet/NavigableSet which has a last() method. Or you can use a List and call mylist.get(mylist.size()-1);

If you really need the last element you should use a List or a SortedSet/NavigableSet. But if all you have is a Collection and you really, really, really need the last element, you could use toArray() or you could use an Iterator and iterate to the end of the list.

For example:

public Object getLastElement(final Collection c) {
    final Iterator itr = c.iterator();
    Object lastElement = itr.next();
    while(itr.hasNext()) {
        lastElement = itr.next();
    }
    return lastElement;
}

Upvotes: 66

ravthiru
ravthiru

Reputation: 9633

If you have Iterable convert to stream and find last element

 Iterator<String> sourceIterator = Arrays.asList("one", "two", "three").iterator();

 Iterable<String> iterable = () -> sourceIterator;


 String last = StreamSupport.stream(iterable.spliterator(), false).reduce((first, second) -> second).orElse(null);

Upvotes: 0

Samad Charania
Samad Charania

Reputation: 171

This should work without converting to List/Array:

collectionName.stream().reduce((prev, next) -> next).orElse(null)

Upvotes: 17

nikolai.serdiuk
nikolai.serdiuk

Reputation: 762

It is not very efficient solution, but working one:

public static <T> T getFirstElement(final Iterable<T> elements) {
    return elements.iterator().next();
}

public static <T> T getLastElement(final Iterable<T> elements) {
    T lastElement = null;

    for (T element : elements) {
        lastElement = element;
    }

    return lastElement;
}

Upvotes: 14

palacsint
palacsint

Reputation: 28865

Iterables.getLast from Google Guava. It has some optimization for Lists and SortedSets too.

Upvotes: 65

assylias
assylias

Reputation: 328619

Or you can use a for-each loop:

Collection<X> items = ...;
X last = null;
for (X x : items) last = x;

Upvotes: 0

Piyush Mattoo
Piyush Mattoo

Reputation: 16125

There isn't a last() or first() method in a Collection interface. For getting the last method, you can either do get(size() - 1) on a List or reverse the List and do get(0). I don't see a need to have last() method in any Collection API unless you are dealing with Stacks or Queues

Upvotes: 0

Nick Garvey
Nick Garvey

Reputation: 3000

A reasonable solution would be to use an iterator if you don't know anything about the underlying Collection, but do know that there is a "last" element. This isn't always the case, not all Collections are ordered.

Object lastElement = null;

for (Iterator collectionItr = c.iterator(); collectionItr.hasNext(); ) {
  lastElement = collectionItr.next();
}

Upvotes: 6

Related Questions