Comment obtenir la dernière valeur d'une ArrayList


598

Comment obtenir la dernière valeur d'une ArrayList?

Je ne connais pas le dernier index de la ArrayList.


164
J'ai voté pour cette question, parce que je me demandais pourquoi il n'y avait pas une telle méthode comme: getLastItem () et je suis venu voir s'il y avait une réponse. list.size () - 1 n'est pas joli.
Nuno Gonçalves

2
@ NunoGonçalves Vous pouvez toujours le sous-classer!
Tim

12
Vous pouvez toujours utiliser une LinkedList qui a la méthodegetLast()
ssedano

6
Liste liée, elle ajoute un tas de frais généraux. Utilisez la goyave comme indiqué ci-dessous: lastElement = Iterables.getLast (iterableList); OU simplement indexer un appel get () avec size () - 1. Ce n'est pas si moche que d'utiliser une liste chaînée quand ce n'est pas nécessaire. Les mises en garde habituelles s'appliquent aux conditions d'exception - voir le javadoc ArrayList.
RichieHH

10
Utiliser list.size () -1 n'est pas joli, mais utiliser une API tierce juste pour cela est pire
Javo

Réponses:


693

Ce qui suit fait partie de l' Listinterface (qu'ArrayList implémente):

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

Eest le type d'élément. Si la liste est vide, getlance un IndexOutOfBoundsException. Vous pouvez trouver toute la documentation de l'API ici .


5
Cela provoquera-t-il une itération de la liste? Cela ne me semble pas très efficace. Je viens de C ++, où il existe de réelles méthodes front () et back () sur l'objet liste, qui sont implémentées en interne avec des références head et tail. Existe-t-il un mécanisme similaire en Java?
Brady

26
Ne fonctionnera pas. que faire si la liste est vide, list.size () retournera 0. et vous vous retrouverez avec list.get (-1);
FRR

18
@feresr hein. Il veut obtenir la dernière valeur de la liste. Bien sûr, cela implique que size () est> 0. Ce serait vrai pour tout type d'implémentation. La lecture jusqu'à la fin aurait sauvé le temps dont vous aviez besoin pour écrire votre commentaire et mon temps pour répondre :) Ma réponse dit à la fin "Si la liste est vide, obtenez lève une IndexOutOfBoundsException"
Johannes Schaub - litb

16
@Brady, il ne provoquera pas d'itération O (n) pour une ArrayList, car comme vous pouvez le deviner, il est soutenu par un tableau. Ainsi, un simple get (<index>) se traduit simplement par une récupération à temps constant à partir d'un tableau. (La source JDK le confirme) Pour les autres implémentations de liste, cela n'est pas garanti, donc par exemple, LinkedList a une méthode getLast () qui est à temps constant.
Peter

9
Je ne comprends pas pourquoi ils ont décidé de mettre en œuvre une lastElement()méthode simple pour leur Vectormais pas pour ArrayList. Qu'est-ce qui se passe avec cette incohérence?
Stefan Dimitrov

211

Il n'y a pas de méthode élégante en Java vanille.

Google Guava

La bibliothèque Google Guava est géniale - consultez leur Iterablesclasse . Cette méthode lancera un NoSuchElementExceptionsi la liste est vide, par opposition à un IndexOutOfBoundsException, comme avec l' size()-1approche typique - je trouve NoSuchElementExceptionbeaucoup plus agréable, ou la possibilité de spécifier un défaut:

lastElement = Iterables.getLast(iterableList);

Vous pouvez également fournir une valeur par défaut si la liste est vide, au lieu d'une exception:

lastElement = Iterables.getLast(iterableList, null);

ou, si vous utilisez les options:

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

3
Savez-vous si cette méthode fait une marche linéaire dans la liste pour trouver le dernier élément?
BillMan

5
@BillMan Dans le cas de HashSet oui, dans le cas de ArrayList non.
Simon

6
Vous devez ajouter cette Iterables.getLastvérification si elle RandomAccessest implémentée et donc si elle accède à l'élément dans O (1).
Karl Richter

1
Au lieu de Option, vous pouvez utiliser le Java natif Optional. Il sera également un peu plus propre: lastElement = Optional.ofNullable(lastElementRaw);.
Little Helper

186

cela devrait le faire:

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

29
n'y a-t-il pas de façon élégante de le faire? : /
kommradHomer

6
Vous devriez probablement au moins démontrer l'attribution ... ArrayList.get est sans effets secondaires.
Antony Stubbs

Est-il trop mesquin pour indiquer que ce qui précède n'affecte / ne renvoie rien?
Brian Agnew

Si une ArrayList n'a qu'un seul enregistrement, une exception s'est produite. Quelle sera la solution?
hasnain_ahmad

2
@hasnain_ahmad, lorsque ArraList a 1 élément, cela fonctionne correctement, vous devriez vous soucier des ArrayList et ArrayList non initialisés avec zéro enregistrement. Et cette réponse traite les deux cas
Farid

27

J'utilise la classe micro-util pour obtenir le dernier (et le premier) élément de la liste:

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

Un peu plus flexible:

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
Utilisez simplement la goyave. Ne réinventez pas
Cliquez sur Upvote

15
@ClickUpvote L'utilisation de la goyave pour une seule méthode minuscule est dans de nombreux cas une exagération. Ma réponse est pour les personnes à la recherche d'une solution Java vanille . Si vous utilisez déjà la goyave dans votre projet, consultez une autre réponse pour une solution basée sur la goyave.
user11153

5
Si vous n'utilisez pas la goyave, vous finissez par écrire de nombreuses classes d'utilitaires comme celle-ci.
Cliquez sur Upvote

6
Parfois, obtenir l'autorisation d'ajouter une bibliothèque tierce peut être beaucoup plus complexe que l'ajout d'une seule classe Java native. Par exemple, les contrats gouvernementaux où ils limitent et filtrent les bibliothèques tierces.
Dave Jarvis

2
isEmptyne vérifie pas si la liste est vide et devrait donc l'être isNullOrEmptyet cela ne fait pas partie de la question - soit vous essayez d'améliorer l'ensemble des réponses, soit vous fournissez des classes d'utilité (qui sont une réinvention).
Karl Richter

10

La size()méthode renvoie le nombre d'éléments dans ArrayList. Les valeurs d'index des éléments sont 0terminées (size()-1), vous pouvez donc utiliser myArrayList.get(myArrayList.size()-1)pour récupérer le dernier élément.



6

Il n'y a aucun moyen élégant d'obtenir le dernier élément d'une liste en Java (par exemple items[-1]en Python).

Vous devez utiliser list.get(list.size()-1).

Lorsque vous travaillez avec des listes obtenues par des appels de méthode compliqués, la solution réside dans la variable temporaire:

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

C'est la seule option pour éviter une version moche et souvent chère voire ne fonctionnant pas:

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

Ce serait bien si un correctif pour cette faille de conception était introduit dans l'API Java.


Je ne vois pas de "défaut de conception" ici, ce que vous évoquez est un cas d'utilisation rare qui ne vaut pas la peine d'être ajouté à l' Listinterface. Pourquoi voudriez-vous appeler une méthode renvoyant une liste, si vous n'êtes intéressé que par le dernier élément? Je ne me souviens pas avoir vu cela auparavant.
Dorian Gray

1
@DorianGray La lecture du dernier élément d'une liste est une opération assez courante et list.get(list.size()-1)est l'exemple minimal montrant le problème. Je suis d'accord que les exemples "avancés" peuvent être controversés et peut-être un cas limite, je voulais juste montrer comment le problème peut se propager davantage. Supposons que la classe de someObjectsoit étrangère, provenant d'une bibliothèque externe.
Tregoreg

Je ne vois pas où c'est assez courant, et si c'est le cas, vous feriez mieux de l'utiliser à la ArrayDequeplace.
Dorian Gray

@DorianGray Cette question a beaucoup de votes positifs et d'opinions, donc il y a beaucoup de gens intéressés à obtenir la dernière valeur d'un ArrayList.
Tregoreg

5

Si vous le pouvez, remplacez le ArrayListpar un ArrayDeque, qui a des méthodes pratiques comme removeLast.


1
Cela signifie au moins un coût linéaire par rapport au coût constant pour un accès direct, mais mérite d'être mentionné.
Karl Richter

@KarlRichter Oui. Cela correspond à l'absence de méthodes comme get (int) dans l'interface d'ArrayDeque. C'est ce que je voulais dire par "si vous le pouvez"; si la liste n'est pas accessible par index, il n'est peut-être pas nécessaire que ce soit une liste.
John Glassmyer

3

Comme indiqué dans la solution, si le Listest vide, un IndexOutOfBoundsExceptionest lancé. Une meilleure solution consiste à utiliser le Optionaltype:

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

Comme vous vous en doutez, le dernier élément de la liste est renvoyé sous la forme Optional:

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

Il traite également gracieusement les listes vides:

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

2

Si vous utilisez une LinkedList à la place, vous pouvez accéder au premier élément et au dernier avec juste getFirst()et getLast()(si vous voulez un moyen plus propre que size () -1 et obtenez (0))

la mise en oeuvre

Déclarez une LinkedList

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

Ensuite , ce sont les méthodes que vous pouvez utiliser pour obtenir ce que vous voulez, dans ce cas , nous parlons de FIRST et LAST élément d'une liste

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

Vous pouvez donc utiliser

mLinkedList.getLast(); 

pour obtenir le dernier élément de la liste.


1

la goyave fournit un autre moyen d'obtenir le dernier élément d'un List:

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

si la liste fournie est vide, elle lance un IndexOutOfBoundsException


1
java.util.Collections#reversele fait aussi.
RoBeaToZ

1
@RoBeaToZ, il le fait, mais il modifie la liste d'origine en itérant à travers elle et retourne vide, donc il ne juge pas approprié à cette fin.
pero_hero

0

Étant donné que l'indexation dans ArrayList commence à 0 et se termine à une place avant la taille réelle, la déclaration correcte pour renvoyer le dernier élément arraylist serait:

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

Par exemple:

si la taille de la liste de tableaux est 5, alors size-1 = 4 retournerait le dernier élément du tableau.


-1

Le dernier élément de la liste est list.size() - 1. La collection est soutenue par un tableau et les tableaux commencent à l'index 0.

L'élément 1 de la liste est donc à l'index 0 du tableau

L'élément 2 de la liste est à l'index 1 du tableau

L'élément 3 de la liste est à l'index 2 du tableau

etc..


3
aucune valeur supplémentaire à la réponse précédente de @ JohannesSchaub
Karl Richter

-3

Que diriez-vous de cela ... Quelque part dans votre classe ...

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

Si vous modifiez votre liste, utilisez listIterator()et répétez le dernier index (c'est-à-dire size()-1respectivement). Si vous échouez à nouveau, vérifiez la structure de votre liste.


-3

Tout ce que vous devez faire est d'utiliser size () pour obtenir la dernière valeur de l'arraylist. Par exemple. si vous ArrayList d'entiers, alors pour obtenir la dernière valeur, vous devrez

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

N'oubliez pas que les éléments d'une liste Arraylist sont accessibles à l'aide de valeurs d'index. Par conséquent, les listes de tableaux sont généralement utilisées pour rechercher des éléments.


4
aucune valeur supplémentaire à la réponse précédente de @ JohannesSchaub
Karl Richter

-4

les tableaux stockent leur taille dans une variable locale appelée «longueur». Étant donné un tableau nommé "a", vous pouvez utiliser ce qui suit pour référencer le dernier index sans connaître la valeur d'index

a [a.length-1]

pour attribuer une valeur de 5 à ce dernier index, vous utiliseriez:

a [a.length-1] = 5;


Ce n'est ArrayListpas un tableau.
glee8e

-6

Alternative utilisant l'API Stream:

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

Entraîne une option du dernier élément.


-7

Dans Kotlin, vous pouvez utiliser la méthode last:

val lastItem = list.last()

10
C'est Java cependant
Jachdich

4
L'une des idées derrière la création de Kotlin était de couvrir les petits côtés inconfortables de Java. Je pense donc qu'il est logique de recommander d'envisager Kotlin, au moins pour les parties de l'application qui effectuent des analyses de données.
Eerik Sven Puudist
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.