Głosowałem za tym pytaniem, ponieważ zastanawiałem się, dlaczego nie ma takiej metody, jak: getLastItem (), i sprawdziłem, czy istnieje odpowiedź. list.size () - 1 nie jest ładne.
Nuno Gonçalves
2
@ NunoGonçalves Zawsze możesz go podklasować!
Tim
12
Zawsze możesz użyć LinkedList, który ma metodęgetLast()
ssedano
6
Lista połączona dodaje całą masę kosztów ogólnych. Użyj Guava, jak pokazano poniżej: lastElement = Iterables.getLast (iterableList); LUB po prostu zindeksuj wywołanie get () za pomocą size () - 1. Nie jest to takie brzydkie w porównaniu do korzystania z połączonej listy, gdy nie jest to wymagane. Zwykłe zastrzeżenia dotyczą warunków wyjątków - patrz ArrayList javadoc.
RichieHH
10
Używanie list.size () -1 nie jest ładne, ale używanie API innych firm tylko do tego jest gorsze
Javo
Odpowiedzi:
692
Oto część Listinterfejsu (który implementuje ArrayList):
E e = list.get(list.size()-1);
Ejest typem elementu. Jeśli lista jest pusta, getwyrzuca an IndexOutOfBoundsException. Całą dokumentację API można znaleźć tutaj .
Czy spowoduje to iterację listy? Nie wydaje mi się to zbyt skuteczne. Pochodzę z C ++, gdzie istnieją rzeczywiste metody front () i back () na obiekcie listy, które są wewnętrznie zaimplementowane z referencjami head i tail. Czy istnieje podobny mechanizm w Javie?
Brady
26
Nie zadziała co jeśli lista jest pusta, list.size () zwróci 0. a skończysz na list.get (-1);
FRR
18
@feresr huh. Chce uzyskać ostatnią wartość z listy. Oczywiście oznacza to, że size () wynosi> 0. Tak byłoby w przypadku każdego rodzaju implementacji. Czytanie do końca zaoszczędziłoby czas potrzebny na napisanie komentarza i czas na udzielenie odpowiedzi :) Moja odpowiedź mówi na końcu: „Jeśli lista jest pusta, wyrzuć wyjątek IndexOutOfBoundsException”
Johannes Schaub - litb
16
@Brady nie spowoduje iteracji O (n) dla ArrayList, ponieważ jak można się domyślić, jest ona wspierana przez tablicę. Zatem proste pobranie (<index>) powoduje po prostu pobieranie z tablicy w czasie stałym. (Potwierdza to źródło JDK) W przypadku innych implementacji listy nie jest to gwarantowane, więc na przykład LinkedList ma metodę getLast (), która jest stała.
Peter
9
Nie rozumiem, dlaczego zdecydowali się zastosować prostą lastElement()metodę dla swoich, Vectorale nie dla ArrayList. O co chodzi z tą niespójnością?
Stefan Dimitrov
211
W waniliowej Javie nie ma eleganckiego sposobu.
Google Guava
Biblioteka Google Guava jest świetna - sprawdź ich Iterablesklasę . Ta metoda rzuci a, NoSuchElementExceptionjeśli lista jest pusta, w przeciwieństwie do IndexOutOfBoundsException, jak w typowym size()-1podejściu - uważam, że jest o NoSuchElementExceptionwiele ładniejsza, lub możliwość określenia wartości domyślnej:
lastElement =Iterables.getLast(iterableList);
Możesz również podać wartość domyślną, jeśli lista jest pusta, zamiast wyjątku:
Prawdopodobnie powinieneś przynajmniej zademonstrować przypisanie go ... ArrayList.get jest wolny od skutków ubocznych.
Antony Stubbs,
Czy jest zbyt małostkowe, aby wskazać, że powyższe niczego nie przypisuje / nie zwraca?
Brian Agnew
Jeśli ArrayList ma tylko jeden rekord, to wystąpił wyjątek. Jakie będzie rozwiązanie?
hasnain_ahmad
2
@hasnain_ahmad, gdy ArraList ma 1 element, działa poprawnie, powinieneś martwić się o niezainicjowane ArrayList i ArrayList z zerowym rekordem. I ta odpowiedź obsługuje oba przypadki
Farid
27
Używam klasy micro-util do uzyskania ostatniego (i pierwszego) elementu listy:
publicfinalclassLists{privateLists(){}publicstatic<T> T getFirst(List<T> list){return list !=null&&!list.isEmpty()? list.get(0):null;}publicstatic<T> T getLast(List<T> list){return list !=null&&!list.isEmpty()? list.get(list.size()-1):null;}}
Nieco bardziej elastyczny:
import java.util.List;/**
* Convenience class that provides a clearer API for obtaining list elements.
*/publicfinalclassLists{privateLists(){}/**
* 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.
*/publicstatic<T> T getFirst(finalList<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.
*/publicstatic<T> T getLast(finalList<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.
*/publicstatic<T> T getFirst(finalList<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.
*/publicstatic<T> T getLast(finalList<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.
*/publicstatic<T>boolean isEmpty(finalList<T> list ){return list ==null|| list.isEmpty();}}
@ClickUpvote Korzystanie z Guava tylko dla jednej małej metody jest w wielu przypadkach przesadą. Moja odpowiedź dotyczy osób poszukujących waniliowego rozwiązania Java . Jeśli już używasz Guava w swoim projekcie, zobacz inną odpowiedź na rozwiązanie oparte na Guava.
user11153,
5
Jeśli nie używasz guawy, kończy się pisanie wielu klas narzędzi takich jak ta.
Kliknij Upvote
6
Czasami uzyskanie pozwolenia na dodanie biblioteki innej firmy może być o wiele bardziej zaangażowane niż dodanie pojedynczej rodzimej klasy Java. Na przykład kontrakty rządowe, w których ograniczają i sprawdzają biblioteki stron trzecich.
Dave Jarvis
2
isEmptynie sprawdza, czy lista jest pusta i dlatego powinna być, isNullOrEmptyi to nie jest częścią pytania - albo próbujesz ulepszyć zestaw odpowiedzi, albo podajesz klasy użyteczności (które są ponownym wynalazkiem).
Karl Richter
10
size()Metoda zwraca liczbę elementów w ArrayList. Wartości indeksu elementów zostały 0przekroczone (size()-1), więc można użyć myArrayList.get(myArrayList.size()-1)do pobrania ostatniego elementu.
Oznacza to co najmniej koszt liniowy w porównaniu ze stałym kosztem bezpośredniego dostępu, ale warto o tym wspomnieć.
Karl Richter
@KarlRichter Tak. To koresponduje z brakiem metod takich jak get (int) w interfejsie ArrayDeque. Właśnie to chciałem zasugerować przez „Jeśli potrafisz”; jeśli lista nie jest dostępna za pomocą indeksu, być może nie musi to być Lista.
John Glassmyer,
5
Nie ma eleganckiego sposobu na uzyskanie ostatniego elementu listy w Javie (w porównaniu np. Do items[-1]Pythona).
Musisz użyć list.get(list.size()-1).
Podczas pracy z listami uzyskanymi za pomocą skomplikowanych wywołań metody obejście polega na zmiennej tymczasowej:
List<E> list = someObject.someMethod(someArgument, anotherObject.anotherMethod());return list.get(list.size()-1);
Jest to jedyna opcja, aby uniknąć brzydkiej i często drogiej lub nawet niedziałającej wersji:
Nie widzę tutaj „wady projektowej”, co przywołujesz, to rzadki przypadek użycia, którego nie warto dodawać do Listinterfejsu. Dlaczego chcesz wywoływać metodę zwracającą Listę, jeśli interesuje Cię tylko ostatni element? Nie pamiętam, że widziałem to wcześniej.
Dorian Gray
1
@DorianGray Czytanie ostatniego elementu z listy jest dość powszechną operacją i list.get(list.size()-1)stanowi minimalny przykład pokazujący problem. Zgadzam się, że „zaawansowane” przykłady mogą być kontrowersyjne i być może zboczone, chciałem tylko pokazać, w jaki sposób problem może dalej się rozprzestrzeniać. Załóżmy, że klasa someObjectjest obca, pochodzi z zewnętrznej biblioteki.
Tregoreg,
Nie widzę, gdzie jest to dość powszechne, a jeśli tak, lepiej użyć ArrayDequezamiast tego.
Dorian Gray
@DorianGray To pytanie ma wiele pozytywnych opinii i poglądów, więc wiele osób jest zainteresowanych uzyskaniem ostatniej wartości ArrayList.
Tregoreg,
3
Jak stwierdzono w rozwiązaniu, jeśli pole Listjest puste, wówczas IndexOutOfBoundsExceptionwyrzucane jest pole an . Lepszym rozwiązaniem jest użycie Optionaltypu:
Jeśli zamiast tego używasz LinkedList, możesz uzyskać dostęp do pierwszego elementu i ostatniego za pomocą just getFirst()i getLast()(jeśli chcesz czystszego sposobu niż size () -1 i uzyskać (0))
To są metody, których możesz użyć, aby uzyskać to, czego chcesz, w tym przypadku mówimy o PIERWSZYM i OSTATNIM elemencie listy
/**
* Returns the first element in this list.
*
* @return the first element in this list
* @throws NoSuchElementException if this list is empty
*/public E getFirst(){finalNode<E> f = first;if(f ==null)thrownewNoSuchElementException();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(){finalNode<E> l = last;if(l ==null)thrownewNoSuchElementException();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(){finalNode<E> f = first;if(f ==null)thrownewNoSuchElementException();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(){finalNode<E> l = last;if(l ==null)thrownewNoSuchElementException();return unlinkLast(l);}/**
* Inserts the specified element at the beginning of this list.
*
* @param e the element to add
*/publicvoid 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
*/publicvoid addLast(E e){
linkLast(e);}
@RoBeaToZ, robi, ale zmienia oryginalną listę poprzez iterację i zwraca void, więc nie uważa się za odpowiedni do tego celu.
pero_hero
0
Ponieważ indeksowanie w ArrayList zaczyna się od 0 i kończy o jedno miejsce przed rzeczywistym rozmiarem, dlatego poprawną instrukcją do zwrócenia ostatniego elementu tablicy będzie:
int last = mylist.get (mylist.size () - 1);
Na przykład:
jeśli rozmiar listy tablic wynosi 5, to rozmiar-1 = 4 zwróci ostatni element tablicy.
brak dodatkowej wartości w stosunku do wcześniejszej odpowiedzi @ JohannesSchaub
Karl Richter
-3
Co powiesz na to ... Gdzieś w klasie ...
List<E> list =newArrayList<E>();privateint i =-1;publicvoid 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 objectreturnnull;// 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 stackreturn object;}
Jeśli zmodyfikujesz listę, użyj listIterator()i powtórz od ostatniego indeksu ( size()-1odpowiednio). Jeśli znowu się nie powiedzie, sprawdź strukturę listy.
Wszystko, co musisz zrobić, to użyć size (), aby uzyskać ostatnią wartość Arraylist. Np. jeśli masz ArrayList liczb całkowitych, to aby uzyskać ostatnią wartość, będziesz musiał
int lastValue = arrList.get(arrList.size()-1);
Pamiętaj, że elementy w Arraylist można uzyskać za pomocą wartości indeksu. Dlatego ArrayLists są zwykle używane do wyszukiwania elementów.
brak dodatkowej wartości w stosunku do wcześniejszej odpowiedzi @ JohannesSchaub
Karl Richter
-4
tablice przechowują swój rozmiar w zmiennej lokalnej o nazwie „length”. Biorąc pod uwagę tablicę o nazwie „a”, możesz użyć następującego polecenia, aby odwołać się do ostatniego indeksu bez znajomości wartości indeksu
a [a.length-1]
aby przypisać wartość 5 do tego ostatniego indeksu, użyłbyś:
Jednym z pomysłów stojących za stworzeniem Kotlina było omówienie małych niewygodnych stron Javy. Myślę więc, że warto zalecić rozważenie Kotlina, przynajmniej dla części aplikacji, które wykonują analizy danych.
getLast()
Odpowiedzi:
Oto część
List
interfejsu (który implementuje ArrayList):E
jest typem elementu. Jeśli lista jest pusta,get
wyrzuca anIndexOutOfBoundsException
. Całą dokumentację API można znaleźć tutaj .źródło
lastElement()
metodę dla swoich,Vector
ale nie dlaArrayList
. O co chodzi z tą niespójnością?W waniliowej Javie nie ma eleganckiego sposobu.
Google Guava
Biblioteka Google Guava jest świetna - sprawdź ich
Iterables
klasę . Ta metoda rzuci a,NoSuchElementException
jeśli lista jest pusta, w przeciwieństwie doIndexOutOfBoundsException
, jak w typowymsize()-1
podejściu - uważam, że jest oNoSuchElementException
wiele ładniejsza, lub możliwość określenia wartości domyślnej:Możesz również podać wartość domyślną, jeśli lista jest pusta, zamiast wyjątku:
lub, jeśli używasz Opcje:
źródło
Iterables.getLast
sprawdzenie, czyRandomAccess
jest zaimplementowane, a zatem czy uzyskuje dostęp do elementu w O (1).Option
możesz użyć natywnej JavaOptional
. Będzie to również nieco czystsze:lastElement = Optional.ofNullable(lastElementRaw);
.powinno to zrobić:
źródło
Używam klasy micro-util do uzyskania ostatniego (i pierwszego) elementu listy:
Nieco bardziej elastyczny:
źródło
isEmpty
nie sprawdza, czy lista jest pusta i dlatego powinna być,isNullOrEmpty
i to nie jest częścią pytania - albo próbujesz ulepszyć zestaw odpowiedzi, albo podajesz klasy użyteczności (które są ponownym wynalazkiem).size()
Metoda zwraca liczbę elementów w ArrayList. Wartości indeksu elementów zostały0
przekroczone(size()-1)
, więc można użyćmyArrayList.get(myArrayList.size()-1)
do pobrania ostatniego elementu.źródło
Używanie lambdas:
źródło
Jeśli możesz, zamień na
ArrayList
naArrayDeque
, który ma wygodne metody, takie jakremoveLast
.źródło
Nie ma eleganckiego sposobu na uzyskanie ostatniego elementu listy w Javie (w porównaniu np. Do
items[-1]
Pythona).Musisz użyć
list.get(list.size()-1)
.Podczas pracy z listami uzyskanymi za pomocą skomplikowanych wywołań metody obejście polega na zmiennej tymczasowej:
Jest to jedyna opcja, aby uniknąć brzydkiej i często drogiej lub nawet niedziałającej wersji:
Byłoby miło, gdyby poprawka do tego błędu projektowego została wprowadzona do API Java.
źródło
List
interfejsu. Dlaczego chcesz wywoływać metodę zwracającą Listę, jeśli interesuje Cię tylko ostatni element? Nie pamiętam, że widziałem to wcześniej.list.get(list.size()-1)
stanowi minimalny przykład pokazujący problem. Zgadzam się, że „zaawansowane” przykłady mogą być kontrowersyjne i być może zboczone, chciałem tylko pokazać, w jaki sposób problem może dalej się rozprzestrzeniać. Załóżmy, że klasasomeObject
jest obca, pochodzi z zewnętrznej biblioteki.ArrayDeque
zamiast tego.ArrayList
.Jak stwierdzono w rozwiązaniu, jeśli pole
List
jest puste, wówczasIndexOutOfBoundsException
wyrzucane jest pole an . Lepszym rozwiązaniem jest użycieOptional
typu:Jak można się spodziewać, ostatni element listy jest zwracany jako
Optional
:Również z wdziękiem radzi sobie z pustymi listami:
źródło
Jeśli zamiast tego używasz LinkedList, możesz uzyskać dostęp do pierwszego elementu i ostatniego za pomocą just
getFirst()
igetLast()
(jeśli chcesz czystszego sposobu niż size () -1 i uzyskać (0))Realizacja
Zadeklaruj LinkedList
To są metody, których możesz użyć, aby uzyskać to, czego chcesz, w tym przypadku mówimy o PIERWSZYM i OSTATNIM elemencie listy
Więc możesz użyć
aby uzyskać ostatni element listy.
źródło
guava zapewnia inny sposób na uzyskanie ostatniego elementu z
List
:last = Lists.reverse(list).get(0)
jeśli podana lista jest pusta, wyrzuca
IndexOutOfBoundsException
źródło
java.util.Collections#reverse
robi to też.Ponieważ indeksowanie w ArrayList zaczyna się od 0 i kończy o jedno miejsce przed rzeczywistym rozmiarem, dlatego poprawną instrukcją do zwrócenia ostatniego elementu tablicy będzie:
int last = mylist.get (mylist.size () - 1);
Na przykład:
jeśli rozmiar listy tablic wynosi 5, to rozmiar-1 = 4 zwróci ostatni element tablicy.
źródło
Ostatnim elementem na liście jest
list.size() - 1
. Kolekcja jest wspierana przez tablicę, a tablice zaczynają się od indeksu 0.Tak więc element 1 na liście ma indeks 0 w tablicy
Element 2 na liście ma indeks 1 w tablicy
Element 3 na liście ma indeks 2 w tablicy
i tak dalej..
źródło
Co powiesz na to ... Gdzieś w klasie ...
źródło
Jeśli zmodyfikujesz listę, użyj
listIterator()
i powtórz od ostatniego indeksu (size()-1
odpowiednio). Jeśli znowu się nie powiedzie, sprawdź strukturę listy.źródło
Wszystko, co musisz zrobić, to użyć size (), aby uzyskać ostatnią wartość Arraylist. Np. jeśli masz ArrayList liczb całkowitych, to aby uzyskać ostatnią wartość, będziesz musiał
Pamiętaj, że elementy w Arraylist można uzyskać za pomocą wartości indeksu. Dlatego ArrayLists są zwykle używane do wyszukiwania elementów.
źródło
tablice przechowują swój rozmiar w zmiennej lokalnej o nazwie „length”. Biorąc pod uwagę tablicę o nazwie „a”, możesz użyć następującego polecenia, aby odwołać się do ostatniego indeksu bez znajomości wartości indeksu
a [a.length-1]
aby przypisać wartość 5 do tego ostatniego indeksu, użyłbyś:
a [a.length-1] = 5;
źródło
ArrayList
nie jest tablica.Alternatywne użycie Stream API:
Wynikiem jest Opcjonalne ostatniego elementu.
źródło
W Kotlin możesz użyć metody
last
:źródło