【发布时间】:2012-01-11 17:53:31
【问题描述】:
我有一个集合,我想获取集合的最后一个元素。最直接、最快速的方法是什么?
一种解决方法是先toArray(),然后返回数组的最后一个元素。还有其他更好的吗?
【问题讨论】:
标签: java collections iterator
我有一个集合,我想获取集合的最后一个元素。最直接、最快速的方法是什么?
一种解决方法是先toArray(),然后返回数组的最后一个元素。还有其他更好的吗?
【问题讨论】:
标签: java collections iterator
Collection 不一定是一组有序的元素,因此可能没有“最后一个”元素的概念。如果您想要订购的东西,您可以使用SortedSet,它有一个last() 方法。或者您可以使用List 并致电mylist.get(mylist.size()-1);
如果你真的需要最后一个元素,你应该使用List 或SortedSet。但是,如果你只有一个 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 可能需要 O(n*lg(n)) (如果你一次构建了它)。因此,根据您期望拥有的物品数量,它可能会相当昂贵。通常,如果您的底层类型是有序的,您至少可以将其转换为 List,即使您不知道它是什么类型的 List。
SortedSet 或至少List。但是,如果您仍然无法对基础类型做出任何假设,那么您将被Collection 公开的 API 卡住,这将不容易找到最后一个元素,因为 Collection 没有概念最后一个元素。因此,您需要自己遍历并找到最后一个元素(toArray 也可以正常工作,前提是您对内存使用没有任何顾虑)。
Object lastElement = null; 返回 null。
Iterables.getLast 来自 Google Guava。
它也对Lists 和SortedSets 进行了一些优化。
【讨论】:
这不是非常有效的解决方案,但可以解决:
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)的情况下,尽可能高效。
一个解决方案可能是:
list.get(list.size()-1)
编辑:您必须先将集合转换为列表,如下所示:new ArrayList(coll)
【讨论】:
这应该可以在不转换为列表/数组的情况下工作:
collectionName.stream().reduce((prev, next) -> next).orElse(null)
【讨论】:
如果您对底层集合一无所知,但知道有一个“最后一个”元素,那么一个合理的解决方案是使用迭代器。并非总是如此,并非所有集合都是有序的。
Object lastElement = null;
for (Iterator collectionItr = c.iterator(); collectionItr.hasNext(); ) {
lastElement = collectionItr.next();
}
【讨论】:
Collection 接口中没有 last() 或 first() 方法。要获得最后一种方法,您可以在 List 上执行 get(size() - 1) 或反转 List 并执行 get(0)。我认为没有必要在任何 Collection API 中使用 last() 方法,除非您正在处理 Stacks 或 Queues
【讨论】:
或者您可以使用 for-each 循环:
Collection<X> items = ...;
X last = null;
for (X x : items) last = x;
【讨论】:
如果你有 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);
【讨论】: