如何获取ArrayList的最后一个值


596

如何获取ArrayList的最后一个值?

我不知道ArrayList的最后一个索引。


164
我赞成这个问题,因为我想知道为什么没有这样的方法:getLastItem()来看看是否有答案。list.size()-1不太漂亮。
NunoGonçalves,2012年

2
@NunoGonçalves您总是可以继承它!
蒂姆(Tim)

12
您可以始终使用具有以下方法的LinkedListgetLast()
ssedano

6
链接列表增加了一大堆开销。使用番石榴,如下所示:lastElement = Iterables.getLast(iterableList); 或简单地用size()-1索引一个get()调用。与不需要链表时相比,它并不难看。有关异常情况的常见警告-请参见ArrayList javadoc。
RichieHH 2014年

10
使用list.size()-1并不漂亮,但是仅使用第三方API则更糟
Javo

Answers:


692

以下是List接口的一部分(由ArrayList实现):

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

E是元素类型。如果列表为空,则get抛出IndexOutOfBoundsException。您可以在此处找到整个API文档。


5
这会导致列表的迭代吗?对我来说,这似乎不是很有效。我来自C ++,列表对象上有实际的front()和back()方法,它们在内部使用head和tail引用实现。Java中有类似的机制吗?
布雷迪2014年

26
不行 如果列表为空,list.size()将返回0。然后您将得到list.get(-1);该结果如何?
FRR

17
@feresr呵呵。他想获取列表中的最后一个值。当然,这意味着size()>0。对于任何类型的实现都是如此。通读到最后将节省您写评论所需的时间以及我的回答时间:)我的回答最后说“如果列表为空,则抛出IndexOutOfBoundsException”
Johannes Schaub-litb

15
@Brady不会导致ArrayList的O(n)迭代,因为您可以猜测,它由数组支持。因此,简单的get(<index>)只能从数组中进行恒定时间的检索。(JDK来源证实了这一点)对于其他列表实现,这是无法保证的,因此,例如,LinkedList具有恒定时间的getLast()方法。
彼得

9
我不明白为什么他们决定lastElement()为自己的人实现一个简单的方法,Vector却没有为他们实现ArrayList。这种不一致是怎么回事?
Stefan Dimitrov

211

原始Java中没有一种优雅的方法。

谷歌番石榴

谷歌番石榴库是伟大的-看看他们的Iterables阶级NoSuchElementException如果列表为空,则此方法将抛出a ,而不是使用IndexOutOfBoundsException,与典型size()-1方法一样-我发现NoSuchElementException更好,或者可以指定默认值:

lastElement = Iterables.getLast(iterableList);

如果列表为空,还可以提供一个默认值,而不是一个异常:

lastElement = Iterables.getLast(iterableList, null);

或者,如果您使用的是选项:

lastElementRaw = Iterables.getLast(iterableList, null);
lastElement = (lastElementRaw == null) ? Option.none() : Option.some(lastElementRaw);

3
您是否知道此方法是否可以线性遍历列表以查找最后一个元素?
BillMan

5
@BillMan在HashSet的情况下,在ArrayList的情况下。
西蒙(Simon)

6
您应该添加该Iterables.getLast检查是否RandomAccess已实现,因此是否要访问O(1)中的项目。
Karl Richter

1
相反Option,您可以使用本机Java Optional。也会更加干净:lastElement = Optional.ofNullable(lastElementRaw);
小帮手

186

这应该做到这一点:

if (arrayList != null && !arrayList.isEmpty()) {
  T item = arrayList.get(arrayList.size()-1);
}

29
有没有时尚的方法?:/
kommradHomer 2012年

6
您可能至少应该演示分配它... ArrayList.get没有副作用。
安东尼·斯塔布斯

指出上面没有分配/返回任何内容是否太琐碎?
Brian Agnew

如果一个ArrayList仅具有一条记录,则发生异常。解决办法是什么?
hasnain_ahmad

2
@hasnain_ahmad,当ArraList具有1个元素时,它可以正常工作,您应该担心未初始化的ArrayList和ArrayList的记录为零。而这个答案处理这两种情况下
法里德

27

我使用micro-util类获取列表的最后一个(和第一个)元素:

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

稍微灵活一些:

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

8
只是用番石榴。不要重新发明
点击Upvote

15
@ClickUpvote在很多情况下,仅将Guava用作一种微小的方法是过大的。我的答案是给那些寻找普通Java解决方案的人。如果您已经在项目中使用了番石榴,请参见基于番石榴的解决方案的其他答案。
user11153 '16

5
如果使用番石榴,那么最终会编写许多这样的实用程序类。
点击

6
有时,获得添加第三方库的许可可能比添加单个本机Java类要复杂得多。例如,政府合同限制和筛选第三方库。
戴夫·贾维斯

2
isEmpty不会检查列表是否为空,是否应该为空,isNullOrEmpty这不是问题的一部分-您尝试增强答案集或提供实用程序类(这是重新发明的)。
Karl Richter

10

size()方法返回ArrayList中的元素数。元素的索引值0通过(size()-1),因此您将myArrayList.get(myArrayList.size()-1)用来检索最后一个元素。



5

如果可以的话,换出ArrayList一个ArrayDeque,它具有方便的方法类似removeLast


1
与直接访问的固定成本相比,这至少意味着线性成本,但值得一提。
Karl Richter

@KarlRichter是的。这与ArrayDeque界面中缺少get(int)之类的方法相对应。我的意思是“如果可以的话”。如果列表未通过索引访问,则可能不必是列表。
John Glassmyer '17

5

没有一种优雅的方法来获取Java中列表的最后一个元素(与items[-1]Python中相比)。

您必须使用list.get(list.size()-1)

当处理通过复杂方法调用获得的列表时,解决方法在于临时变量:

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

这是避免使用丑陋且通常昂贵甚至不工作的版本的唯一选择:

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

如果针对Java API引入了针对此设计缺陷的修复程序,那就太好了。


我在这里看不到“设计缺陷”,您提到的是一个罕见的用例,不值得添加到List接口中。如果只对最后一个元素感兴趣,为什么要调用返回列表的方法?我不记得我以前曾经看过。
多里安·格雷

1
@DorianGray从列表中读取最后一个元素是很常见的操作,并且list.get(list.size()-1)是显示此问题的最小示例。我同意“高级”示例可能会引起争议,甚至可能是一个极端案例,我只是想说明问题如何进一步传播。假设的类someObject是外部的,来自外部库。
Tregoreg

我看不到这在哪里很常见,如果是,最好ArrayDeque改用。
多里安·格雷

@DorianGray这个问题有很多支持和观点,所以有很多人有兴趣获取an的最后一个值ArrayList
Tregoreg

3

如解决方案中所述,如果Listan IndexOutOfBoundsException为空,则抛出an 。更好的解决方案是使用以下Optional类型:

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

如您所料,列表的最后一个元素以形式返回Optional

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

它还可以很好地处理空列表:

var emptyList = List.<Integer>of();
assert ListUtils.last(emptyList).orElse(-1) == -1;

2

如果改用LinkedList,则可以使用just getFirst()和访问第一个元素和最后一个元素getLast()(如果您希望使用比size()-1和get(0)更为简洁的方法)

实作

声明一个LinkedList

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

这就是您可以用来获取所需内容的方法,在这种情况下,我们正在谈论列表的FIRSTLAST元素

/**
     * 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);
    }

所以,那么您可以使用

mLinkedList.getLast(); 

获取列表的最后一个元素。


1

番石榴提供了另一种从中获取最后一个元素的方法List

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

如果提供的列表为空,则抛出 IndexOutOfBoundsException


1
java.util.Collections#reverse也这样做。
RoBeaToZ

1
@RoBeaToZ可以,但是它通过迭代原始列表来更改原始列表并返回void,因此它不适合用于此目的。
pero_hero

0

由于ArrayList中的索引从0开始并在实际大小之前结束一位,因此返回最后一个arraylist元素的正确语句将是:

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

例如:

如果数组列表的大小为5,则size-1 = 4将返回最后一个数组元素。


-1

列表中的最后一项是list.size() - 1。集合由数组支持,数组从索引0开始。

因此列表中的元素1在数组的索引0处

列表中的元素2在数组的索引1处

列表中的元素3在数组的索引2处

等等..


3
@JohannesSchaub的早期答案没有其他价值
Karl Richter

-3

怎么样。.在你课堂的某个地方...

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

-3

如果您修改列表,请使用listIterator()并从最后一个索引开始迭代(size()-1分别)。如果再次失败,请检查列表结构。


-3

您需要做的就是使用size()获得Arraylist的最后一个值。对于前。如果您是整数的ArrayList,那么要获取最后一个值,您将必须

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

请记住,可以使用索引值访问Arraylist中的元素。因此,ArrayList通常用于搜索项目。


4
@JohannesSchaub的早期答案没有其他价值
Karl Richter

-4

数组将其大小存储在称为“长度”的局部变量中。给定名为“ a”的数组,您可以使用以下内容引用最后一个索引,而无需知道索引值

a [a.length-1]

为最后一个索引分配值5,您可以使用:

a [a.length-1] = 5;


ArrayList不是数组。
glee8e 17-4-5

-6

使用Stream API的替代方法:

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

结果是最后一个元素的Optional。


-7

在Kotlin中,您可以使用方法last

val lastItem = list.last()

9
但是,这是Java
Jachdich

4
创建Kotlin的想法之一是涵盖Java的一些不舒服之处。因此,我认为建议至少在应用程序中执行数据analasys的部分考虑考虑Kotlin是有意义的。
Eerik Sven Puudist
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.