Java获取集合的最后一个元素

64

我有一个集合,想获取集合中最后一个元素。最简单且快速的方法是什么?

一种解决方法是先使用toArray()方法,然后返回数组的最后一个元素。还有其他更好的方式吗?

9个回答

66
Collection不一定是元素有序的集合,因此可能不存在“last”元素的概念。如果您需要一个有序的集合,可以使用SortedSet/NavigableSet,它具有 last() 方法。或者您可以使用List并调用mylist.get(mylist.size()-1)来获取最后一个元素。
如果您确实需要最后一个元素,应该使用ListSortedSet/NavigableSet。但是,如果您只有一个Collection并且确实非常需要最后一个元素,您可以使用toArray()或使用迭代器Iterator并迭代到列表末尾。
例如:
public Object getLastElement(final Collection c) {
    final Iterator itr = c.iterator();
    Object lastElement = itr.next();
    while(itr.hasNext()) {
        lastElement = itr.next();
    }
    return lastElement;
}

我只有一个集合可用,我不知道它的基本类型是数组、列表还是其他类型。因此,要使用SortedSet,我首先必须使用该集合构造SortedSet,然后进行其余的工作。这样做会很昂贵吗? - tom
谢谢@Jack,假设我的数据在返回给我时已经排序好了,因为它们确实是这样的,那么还会有其他解决方案吗? - tom
1
当给出一个空集合时,这会抛出一个NullPointerException。相反,使用Object lastElement = null;来返回空集合的情况下的null值。 - Markus Pscheidt
也可以将该方法设为静态的。 - riddle_me_this
这个方法的缺点是在 while 循环的每次迭代中都会重新分配 lastElement 变量,但它能正常工作。 - Alex Vergara
显示剩余5条评论

61
来自Google Guava的

Iterables.getLast 可以获取一个可迭代对象的最后一个元素,对于ListSortedSet也进行了一些优化。


4
不具备空值安全性。如果你的集合为空,你将会得到 NPE 错误。 - DenisS
3
如果您的任何内容为空,Java会引发NPE异常,请进行检查。 - maksimov

16

这应该可以在不转换为列表/数组的情况下工作:

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

14

这不是一个非常高效的解决方案,但它是有效的:

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;
}

实际上它非常高效。事实上,它的效率已经达到了最大化,而不需要尝试将可迭代对象转换为任何更具体的类型(好吧,List除外)。 - Dmitry Ginzburg

10

那么一个解决方案可能是:

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

编辑:在进行下一步操作之前,您需要将集合转换为列表,可以像这样:new ArrayList(coll)


所以我需要先使用集合构建列表。就性能而言,这与toArray解决方案有什么不同吗? - tom
如果你只是获取最后一个元素,使用toArray()比构建ArrayList更有效率。 - mwk
1
问题指的是它是一个集合而不是列表。现在,将其转换为列表只是为了拥有最后一个元素是一个糟糕的解决方案,如果你有大型集合,这可能会导致性能瓶颈。相反,使用Guava的Iterable.getLast方法即可。 - javadev
如果你必须要进行转换(这将复制它),那么你最好使用其中一种迭代解决方案... - Bill K

6

如果您不知道底层集合的情况,但是确定存在“last”元素,一个合理的解决方案是使用迭代器。但并非所有集合都是有序的。

Object lastElement = null;

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

1
正确,我不知道集合的底层类型。但如果它是一个大集合,那么它将是一个O(N)解决方案。我基本上正在寻找一个O(1)解决方案。 - tom
1
那是不可能的。考虑尝试获取单向链表的最后一个元素。该操作必须是O(n),没有通用的O(1)答案。 - Nick Garvey

0

在集合接口中没有last()first()方法。要获取最后一个方法,您可以在列表上执行get(size() - 1),或者反转列表并执行get(0)。我认为除非您正在处理StacksQueues,否则不需要在任何集合API中使用last()方法。


集合也没有获取数据的方法。 - tom
1
当然!我指的是Collection接口的List实现。 - Piyush Mattoo

0

或者你可以使用 for-each 循环:

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

0

如果您有Iterable,请将其转换为流并查找最后一个元素

 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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接