Reputation: 14513
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
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
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
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
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
Reputation: 171
This should work without converting to List/Array:
collectionName.stream().reduce((prev, next) -> next).orElse(null)
Upvotes: 17
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
Reputation: 28865
Iterables.getLast
from Google Guava.
It has some optimization for List
s and SortedSet
s too.
Upvotes: 65
Reputation: 328619
Or you can use a for-each loop:
Collection<X> items = ...;
X last = null;
for (X x : items) last = x;
Upvotes: 0
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
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