Как получить последнее значение ArrayList

Как я могу получить последнее значение ArrayList?

Я не знаю последний индекс ArrayList.


person Jessy    schedule 26.03.2009    source источник
comment
Я поддержал этот вопрос, потому что мне было интересно, почему нет такого метода, как getLastItem (), и я пришел посмотреть, есть ли ответ. list.size () - 1 некрасиво.   -  person Nuno Gonçalves    schedule 23.11.2012
comment
@ NunoGonçalves Вы всегда можете создать подкласс!   -  person Tim    schedule 26.07.2013
comment
Вы всегда можете использовать LinkedList с методом getLast()   -  person ssedano    schedule 26.04.2014
comment
Связанный листинг добавляет целую кучу накладных расходов. Используйте Guava, как показано ниже: lastElement = Iterables.getLast (iterableList); ИЛИ просто проиндексируйте вызов get () с size () - 1. Это не так уродливо по сравнению с использованием связанного списка, когда он не требуется. В отношении условий исключения применяются обычные предостережения - см. Javadoc ArrayList.   -  person RichieHH    schedule 23.05.2014
comment
Использование list.size () -1 некрасиво, но использование стороннего API только для этого хуже   -  person Javo    schedule 19.07.2017
comment
@Javo Я согласен с вами насчет партии 3dr, если это единовременная ситуация, но давайте будем честными: существует множество ситуаций, в которых вам будет полезно иметь в своем приложении сторонний API, такой как Guava или Apache Commons. Новички могут не знать о них или о том, что они умеют, или могут не думать о них, когда ищут ответы. Вероятно, вы будете использовать эти API несколько раз. Следовательно, мне интересно иметь как ванильные решения java, так и API-интерфейсы, чтобы люди могли открывать для себя эти API-интерфейсы, если захотят.   -  person Carrm    schedule 03.01.2019
comment
Я выбрал этот вопрос, чтобы вспомнить, насколько безумным стал мир программирования ...   -  person Matthieu    schedule 08.07.2019
comment
Я не понимаю, что плохого в list.size () - 1, очень понятно, что это значит. Или вы бы предпочли обозначение Perl: $ list [$ # list], что было бы лучше?   -  person soger    schedule 26.10.2020
comment
@soger Нет, но могло быть и хуже, это не удовлетворительная причина, чтобы не иметь удобочитаемого метода, такого как getLastElement(), быть частью java.util.List API.   -  person AMTerp    schedule 09.04.2021


Ответы (22)


Следующее является частью интерфейса List ( который реализует ArrayList):

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

E - это тип элемента. Если список пуст, get выдает _5 _. Вы можете найти всю документацию по API здесь.

person Johannes Schaub - litb    schedule 26.03.2009
comment
Приведет ли это к повторению списка? Мне это кажется не очень эффективным. Я пришел из C ++, где есть фактические методы front () и back () для объекта списка, которые внутренне реализованы с помощью ссылок head и tail. Есть ли аналогичный механизм в Java? - person Brady; 13.10.2014
comment
Не получится. что, если список пуст, list.size () вернет 0. и вы получите list.get (-1); - person frankelot; 21.01.2015
comment
@feresr да. Он хочет получить последнее значение в списке. Конечно, это подразумевает, что size () => 0. Это будет верно для любой реализации. Дочитание до конца сэкономило бы время, необходимое для написания вашего комментария, и мое время для ответа :) В моем ответе сказано в конце Если список пуст, get выдает исключение IndexOutOfBoundsException - person Johannes Schaub - litb; 23.01.2015
comment
@Brady это не вызовет итерацию O (n) для ArrayList, потому что, как вы можете догадаться, он поддерживается массивом. Таким образом, простой метод get (‹index›) просто приводит к постоянному извлечению из массива. (Источник JDK подтверждает это) Для других реализаций списков это не гарантируется, поэтому, например, LinkedList имеет метод getLast (), который является постоянным по времени. - person Peter; 19.03.2015
comment
Нет ли более элегантного способа сделать это? Когда я писал код в основном на C / C ++, я помню, что возможность использовать list.back() или что-то подобное ... было бы хорошей функцией в Java. - person Pixel; 29.07.2015
comment
@poirot, реализация метода List.back (), скорее всего, в любом случае будет делать именно то, что показано здесь. - person sherrellbc; 23.03.2016
comment
@sherrellbc, он будет делать то же самое. Если бы в Java была эта функция, я бы сэкономил время на вводе текста. - person Pixel; 24.03.2016
comment
Я не могу понять, почему они решили реализовать простой lastElement() метод для своих Vector, но не для ArrayList. Что случилось с этой непоследовательностью? - person Stefan Dimitrov; 07.09.2016
comment
Я погуглил, потому что мой мозг подсказывает, что должен быть более простой способ. Java начинает казаться таким низкоуровневым. - person Fletch; 21.08.2017
comment
list.get(list.size()--) работает или не работает? - person ; 19.12.2017
comment
Наверное, глупо, но гарантирует ли List::get последовательный возврат? Т.е. list.get(0); гарантированно будет элементом первым (если он существует, бла-бла), list.get(1) вторым и т. д.? Или List реализации могут индексировать по своему усмотрению, пока их Iterator функции расположены в соответствующем порядке? - person BeUndead; 10.10.2018
comment
@ user2478398 Он обеспечивает последовательные возвраты guaRantee. - person Dorian Gray; 20.10.2019

В ванильной Java нет элегантного способа.

Google Guava

Библиотека Google Guava великолепна - ознакомьтесь с их _ 1_ class. Этот метод вызовет 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);
person Antony Stubbs    schedule 28.12.2012
comment
Вы знаете, выполняет ли этот метод линейный обход списка, чтобы найти последний элемент? - person BillMan; 20.02.2013
comment
@BillMan В случае HashSet - да, в случае ArrayList - нет. - person Simon; 19.08.2013
comment
Вы должны добавить, что Iterables.getLast проверяет, реализовано ли RandomAccess и, следовательно, обращается ли он к элементу в O (1). - person Karl Richter; 23.06.2017
comment
Вместо Option можно использовать родную Java Optional. Также будет немного чище: lastElement = Optional.ofNullable(lastElementRaw);. - person Little Helper; 07.05.2019

это должно сделать это:

if (arrayList != null && !arrayList.isEmpty()) {
  T item = arrayList.get(arrayList.size()-1);
}
person Henrik Paul    schedule 26.03.2009
comment
нет ли гладкого способа сделать это? : / - person kommradHomer; 05.09.2012
comment
Вы, вероятно, должны хотя бы продемонстрировать его назначение ... ArrayList.get не имеет побочных эффектов. - person Antony Stubbs; 28.12.2012
comment
Не слишком ли мелочно указывать, что вышеперечисленное ничего не присваивает / не возвращает? - person Brian Agnew; 23.03.2017
comment
Если в ArrayList есть только одна запись, возникло исключение. Какое будет решение? - person hasnain_ahmad; 12.04.2018
comment
@hasnain_ahmad, когда ArraList имеет 1 элемент, он работает правильно, вам следует беспокоиться о неинициализированных ArrayList и ArrayList с нулевой записью. И этот ответ обрабатывает оба случая - person Farid; 22.07.2018

Я использую класс 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();
  }
}
person user11153    schedule 10.10.2014
comment
Просто используйте гуаву. Не изобретайте заново - person Ali; 04.11.2016
comment
@ClickUpvote Использование Guava только для одного крошечного метода во многих случаях является излишним. Мой ответ для людей, которые ищут ванильное решение для Java. Если вы уже используете Guava в своем проекте, см. Другой ответ для решения на основе Guava. - person user11153; 04.11.2016
comment
Если вы не используете гуаву, вы в конечном итоге напишете множество служебных классов, подобных этому. - person Ali; 05.11.2016
comment
Иногда получение разрешения на добавление сторонней библиотеки может быть намного сложнее, чем добавление одного собственного Java-класса. Например, государственные контракты, в которых они ограничивают и проверяют сторонние библиотеки. - person Dave Jarvis; 31.03.2017
comment
isEmpty не проверяет, является ли список пустым и, следовательно, должен быть isNullOrEmpty, и это не является частью вопроса - либо вы пытаетесь расширить набор ответов, либо предоставляете вам служебные классы (которые являются повторным изобретением). - person Karl Richter; 23.06.2017

Метод size() возвращает количество элементов в ArrayList. Значения индекса элементов от 0 до (size()-1), поэтому вы должны использовать myArrayList.get(myArrayList.size()-1) для получения последнего элемента.

person Ken Paul    schedule 26.03.2009

Не существует элегантного способа получить последний элемент списка в 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.

person Tregoreg    schedule 05.06.2019
comment
Я не вижу здесь недостатка в дизайне, вы говорите о редком варианте использования, который не стоит добавлять в интерфейс List. Зачем вам вызывать метод, возвращающий список, если вас интересует только последний элемент? Я не помню, чтобы видел такое раньше. - person Dorian Gray; 20.10.2019
comment
@DorianGray Чтение последнего элемента из списка - довольно распространенная операция, а list.get(list.size()-1) - минимальный пример, показывающий проблему. Я согласен с тем, что расширенные примеры могут быть спорными и, возможно, крайним случаем, я просто хотел показать, как проблема может распространяться дальше. Предположим, что класс someObject является чужим, происходящим из внешней библиотеки. - person Tregoreg; 20.10.2019
comment
Я не вижу, где это довольно распространено, и если это так, вам лучше вместо этого использовать ArrayDeque. - person Dorian Gray; 20.10.2019
comment
@DorianGray У этого вопроса много голосов и просмотров, поэтому есть много людей, заинтересованных в получении последнего значения ArrayList. - person Tregoreg; 20.10.2019

Используя лямбды:

Function<ArrayList<T>, T> getLast = a -> a.get(a.size() - 1);
person Luis Vieira Damiani    schedule 08.05.2018

Если можете, замените ArrayList на ArrayDeque, у которого есть такие удобные методы, как removeLast.

person John Glassmyer    schedule 12.12.2014
comment
Это означает, по крайней мере, линейные затраты по сравнению с постоянными затратами на прямой доступ, но это стоит упомянуть. - person Karl Richter; 23.06.2017
comment
@KarlRichter Да. Это соответствует отсутствию таких методов, как get (int) в интерфейсе ArrayDeque. Это то, что я хотел предложить, если вы можете; если доступ к списку не осуществляется по индексу, возможно, это не обязательно список. - person John Glassmyer; 13.07.2017

Если вместо этого вы используете LinkedList, вы можете получить доступ к первому и последнему элементам с помощью только getFirst() и getLast() (если вам нужен более чистый способ, чем size () -1 и получить (0))

Реализация

Объявить LinkedList

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

Затем это методы, которые вы можете использовать, чтобы получить то, что хотите, в данном случае мы говорим о ПЕРВОМ и ПОСЛЕДНЕМ элементах списка.

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

чтобы получить последний элемент списка.

person Gastón Saillén    schedule 11.11.2018
comment
Лучший ответ здесь! - person marcolopes; 01.10.2020

Как указано в решении, если List пусто, то бросается IndexOutOfBoundsException. Лучшее решение - использовать тип 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;
person Colin Breame    schedule 09.04.2019

Если у вас есть весенний проект, вы также можете использовать CollectionUtils.lastElement из Spring (javadoc), и вам не нужно добавлять дополнительную зависимость, например Google Guave, если в этом не было необходимости раньше.

Это нулевое значение, поэтому, если вы передадите null, вы просто получите взамен null. Однако будьте осторожны при обращении с ответом.

Вот несколько модульных тестов, чтобы продемонстрировать их:

@Test
void lastElementOfList() {
    var names = List.of("John", "Jane");

    var lastName = CollectionUtils.lastElement(names);

    then(lastName)
        .as("Expected Jane to be the last name in the list")
        .isEqualTo("Jane");
}

@Test
void lastElementOfSet() {
    var names = new TreeSet<>(Set.of("Jane", "John", "James"));

    var lastName = CollectionUtils.lastElement(names);

    then(lastName)
        .as("Expected John to be the last name in the list")
        .isEqualTo("John");
}

Примечание: org.assertj.core.api.BDDAssertions#then(java.lang.String) используется для утверждений.

person Pim Hazebroek    schedule 21.08.2020

Один лайнер, который учитывает пустые списки, будет:

T lastItem = list.size() == 0 ? null : list.get(list.size() - 1);

Или, если вам не нравятся нулевые значения (и производительность не является проблемой):

Optional<T> lastItem = list.stream().reduce((first, second) -> second);
person Craigo    schedule 02.01.2021

Поскольку индексирование в ArrayList начинается с 0 и заканчивается на одно место до фактического размера, правильным оператором для возврата последнего элемента arrayylist будет:

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

Например:

если размер списка массивов равен 5, то size-1 = 4 вернет последний элемент массива.

person shravyaverma    schedule 13.01.2020

guava предоставляет другой способ получить последний элемент из List:

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

если предоставленный список пуст, он выдает IndexOutOfBoundsException

person pero_hero    schedule 09.04.2020
comment
java.util.Collections#reverse тоже делает это. - person RoBeaToZ; 22.04.2020
comment
@RoBeaToZ, это так, но он изменяет исходный список, перебирая его и возвращая void, поэтому он не считает подходящим для этой цели. - person pero_hero; 22.04.2020
comment
Достаточно дорого за один элемент. Представьте, что в вашем списке около 1 000 000 записей. - person philburns; 24.11.2020
comment
@philburns этот вызов находится в O (1) независимо от размера списка - person pero_hero; 14.04.2021

Это сработало для меня.

private ArrayList<String> meals;
public String take(){
  return meals.remove(meals.size()-1);
}
person Med Sep    schedule 13.12.2020

Последний элемент в списке - list.size() - 1. Коллекция поддерживается массивом, и массивы начинаются с индекса 0.

Таким образом, элемент 1 в списке имеет индекс 0 в массиве

Элемент 2 в списке находится под индексом 1 в массиве

Элемент 3 в списке находится под индексом 2 в массиве

и так далее..

person MircoProgram    schedule 25.11.2015
comment
нет дополнительной ценности для более раннего ответа @ JohannesSchaub - person Karl Richter; 23.06.2017

Как насчет этого .. Где-то в вашем классе ...

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;
    }
person rokrfellr    schedule 12.12.2014

Если вы измените свой список, используйте listIterator() и выполнить итерацию с последнего индекса (т.е. size()-1 соответственно). Если вы снова потерпите неудачу, проверьте структуру своего списка.

person dae    schedule 28.10.2010

Все, что вам нужно сделать, это использовать size (), чтобы получить последнее значение Arraylist. Например, если вы ArrayList целых чисел, то для получения последнего значения вам нужно будет

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

Помните, что к элементам в Arraylist можно получить доступ, используя значения индекса. Таким образом, ArrayLists обычно используются для поиска элементов.

person user4660857    schedule 14.02.2016
comment
нет дополнительной ценности для более раннего ответа @ JohannesSchaub - person Karl Richter; 23.06.2017

массивы хранят свой размер в локальной переменной, называемой «длина». Учитывая массив с именем "a", вы можете использовать следующее для ссылки на последний индекс, не зная значения индекса.

a [a.length-1]

чтобы присвоить этому последнему индексу значение 5, вы должны использовать:

a [a.length-1] = 5;

person closeab    schedule 05.04.2017
comment
Это ArrayList, а не массив. - person glee8e; 05.04.2017

Альтернатива с использованием Stream API:

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

Приводит к необязательному последнему элементу.

person Terran    schedule 04.12.2018

В Котлине вы можете использовать метод last:

val lastItem = list.last()
person Ollie    schedule 08.09.2019
comment
Однако это java - person Jachdich; 03.10.2019
comment
Одна из идей создания Kotlin заключалась в том, чтобы скрыть небольшие неудобные стороны Java. Поэтому я думаю, что имеет смысл рекомендовать рассмотреть Kotlin, по крайней мере, для тех частей приложения, которые выполняют анализ данных. - person Eerik Sven Puudist; 09.02.2020