Bir ArrayList'in son değerini alma


597

Bir ArrayList'in son değerini nasıl alabilirim?

ArrayList'in son dizinini bilmiyorum.


164
Bu soruyu iptal ettim, çünkü neden böyle bir yöntem olmadığını merak ediyordum: getLastItem () ve bir cevap olup olmadığını görmeye geldim. list.size () - 1 hoş değil.
Nuno Gonçalves

2
@ NunoGonçalves Her zaman alt sınıflandırabilirsiniz!
Tim

12
Her zaman şu yöntemi içeren bir LinkedList kullanabilirsinizgetLast()
ssedano

6
Bağlantılı liste, genel bir yığın ekler. Guava'yı aşağıda gösterildiği gibi kullanın: lastElement = Iterables.getLast (iterableList); VEYA sadece size get () çağrısını size () ile indeksleyin. 1. Gerekmediğinde bağlantılı bir liste kullanmaya kıyasla o kadar çirkin değil. İstisna koşulları ile ilgili olağan uyarılar geçerlidir - ArrayList javadoc'a bakınız.
RichieHH

10
List.size () -1 kullanmak hoş değil, ancak bunun için bir 3. taraf API kullanmak daha kötü
Javo

Yanıtlar:


692

Aşağıdakiler Listarabirimin bir parçasıdır (ArrayList tarafından uygulanır):

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

Eöğe türüdür. Liste boşsa, getbir IndexOutOfBoundsException. API belgelerinin tamamını burada bulabilirsiniz .


5
Bu listenin tekrarlanmasına neden olur mu? Bu benim için çok verimli görünmüyor. Ben liste nesnesi üzerinde iç ve kuyruk başvuruları ile dahili olarak uygulanan gerçek front () ve back () yöntemleri olan C ++, geliyor. Java'da benzer bir mekanizma var mı?
Brady

26
Çalışmaz. liste boşsa, list.size () 0 döndürür ve list.get (-1) ile sonuçlanırsınız;
FRR

18
@feresr hah. Listedeki son değeri almak istiyor. Tabii ki bu, boyutun (0) olduğunu gösterir. Bu, her türlü uygulama için geçerli olacaktır. Sonuna kadar okumak, yorumunuzu yazmak için gereken zamanı ve cevaplama zamanımı kaydeder :) Cevabım sonunda "Liste boşsa, get bir IndexOutOfBoundsException" atar
Johannes Schaub - litb

16
@Brady bir ArrayList için O (n) yinelemesine neden olmaz, çünkü tahmin edebileceğiniz gibi bir dizi tarafından desteklenir. Yani basit bir get (<index>) sadece bir diziden sabit zamanlı geri alma ile sonuçlanır. (JDK kaynağı bunu onaylar) Diğer liste uygulamaları için bu garanti edilmez, bu nedenle örneğin LinkedList sabit zamanlı bir getLast () yöntemine sahiptir.
Peter

9
Neden basit bir lastElement()yöntem uygulamaya karar verdiklerini anlayamıyorum Vectorama bunun için değil ArrayList. Bu tutarsızlığın nesi var?
Stefan Dimitrov

211

Vanilya Java'da zarif bir yol yoktur.

Google Guava

Google Guava kütüphane büyük - onların kontrol Iterablessınıfı . Bu yöntem , tipik bir yaklaşımda olduğu NoSuchElementExceptiongibi, bir liste yerine boşsa atar - Çok daha hoş buluyorum veya bir varsayılan belirleme yeteneği:IndexOutOfBoundsExceptionsize()-1NoSuchElementException

lastElement = Iterables.getLast(iterableList);

Liste boşsa istisna yerine varsayılan bir değer de sağlayabilirsiniz:

lastElement = Iterables.getLast(iterableList, null);

veya Seçenekler'i kullanıyorsanız:

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

3
Bu yöntemin son öğeyi bulmak için listede doğrusal bir yürüyüş yapıp yapmadığını biliyor musunuz?
BillMan

5
@BillMan HashSet için evet, ArrayList no.
Simon

6
Uygulanıp uygulanmadığını ve dolayısıyla O (1) 'deki öğeye erişilip erişilmediğini Iterables.getLastkontrol etmelisiniz RandomAccess.
Karl Richter

1
Bunun yerine Option, yerel Java'yı kullanabilirsiniz Optional. Bu da biraz daha temiz olacaktır: lastElement = Optional.ofNullable(lastElementRaw);.
Küçük Yardımcı

186

bunu yapmalı:

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

29
Bunu yapmanın şık bir yolu yok mu? : /
kommradHomer

6
Muhtemelen en azından onu atadığınızı göstermelisiniz ... ArrayList.get yan etki ücretsizdir.
Antony Stubbs

Yukarıdakilerin hiçbir şey atamadığını / iade etmediğini belirtmek çok küçük mü?
Brian Agnew

Bir ArrayList öğesinin yalnızca bir kaydı varsa, bir istisna oluşur. Çözüm ne olacak?
hasnain_ahmad

2
@hasnain_ahmad, ArraList düzgün çalıştığında 1 elemente sahipse, sıfır kayıt ile başlatılmamış ArrayList ve ArrayList hakkında endişelenmelisiniz. Ve bu cevap her iki durumu da ele alıyor
Farid

27

Listenin son (ve ilk) öğesini almak için micro-util sınıfı kullanıyorum:

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

Biraz daha esnek:

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
Sadece guava kullan. Tekrar icat etmeyin
16:49

15
@ClickUpvote Guava'yı sadece küçük bir yöntem için kullanmak çoğu durumda aşırıya kaçmaktır. Cevabım vanilya Java çözümü arayan insanlar için . Projenizde zaten Guava kullanıyorsanız, Guava tabanlı çözüm için diğer cevaba bakın.
user11153

5
Eğer varsa yok guava kullanmak, bu gibi yarar sınıfların sürü yazma sonunda.
Upvote

6
Bazen bir üçüncü taraf kitaplığı ekleme izni almak, tek bir yerel Java sınıfı eklemekten çok daha karmaşık olabilir. Örneğin, üçüncü taraf kütüphanelerini sınırlandırıp taradıkları yerlerde hükümet sözleşmeleri.
Dave Jarvis

2
isEmptylistenin boş olup olmadığını ve bu nedenle olması gerekip gerekmediğini kontrol etmez isNullOrEmptyve bu sorunun bir parçası değildir - ya cevap kümesini geliştirmeye çalışırsınız ya da size (yeniden buluş olan) faydalı sınıflar sağlarsınız.
Karl Richter

10

size()Yöntem ArrayList'in elemanlarının sayısını verir. Öğelerin dizin değerleri 0geçer (size()-1), bu nedenle myArrayList.get(myArrayList.size()-1)son öğeyi almak için kullanılır .



5

Yapabiliyorsanız, gibi uygun yöntemlere sahip olan ArrayListbir için değiştirin .ArrayDequeremoveLast


1
Bu, doğrudan erişim için sabit maliyete kıyasla en azından doğrusal maliyet anlamına gelir, ancak söz etmeye değer.
Karl Richter

@KarlRichter Evet. Bu, ArrayDeque'nin arayüzünde get (int) gibi yöntemlerin bulunmamasına karşılık gelir. "Eğer yapabilirsen" önermek istediğim budur; listeye dizin tarafından erişilmiyorsa, o zaman bir Liste olması gerekmez.
John Glassmyer

5

Java'da bir listenin son öğesini almanın zarif bir yolu yoktur (örneğin items[-1]Python'dakine kıyasla ).

Kullanmak zorundasın list.get(list.size()-1).

Karmaşık yöntem çağrıları ile elde edilen listelerle çalışırken geçici çözüm geçici değişkendir:

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

Bu çirkin ve genellikle pahalı veya hatta çalışmıyor sürümü önlemek için tek seçenek:

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

Bu tasarım kusuru düzeltmesinin Java API'ye sunulması güzel olurdu.


Burada bir "tasarım kusuru" görmüyorum, ortaya çıkardığınız şey Listarayüze eklenmeye değmeyecek nadir bir kullanım durumudur . Yalnızca son öğeyle ilgileniyorsanız neden Liste döndüren bir yöntemi çağırmak istersiniz? Bunu daha önce gördüğümü hatırlamıyorum.
Dorian Gray

1
@DorianGray Listedeki son öğeyi okumak oldukça yaygın bir işlemdir ve list.get(list.size()-1)sorunu gösteren en az örnektir. "İleri" örneklerin tartışmalı olabileceğini ve büyük olasılıkla bir son durum olabileceğini kabul ediyorum, sadece sorunun nasıl daha da yayılabileceğini göstermek istedim. someObjectDış kütüphaneden gelen sınıfının yabancı olduğunu varsayalım .
Tregoreg

Bunun oldukça yaygın olduğunu görmüyorum ve eğer öyleyse, daha iyi kullanırsınız ArrayDeque.
Dorian Gray

@DorianGray Bu soru çok sayıda oy ve görüşe sahiptir, bu yüzden bir kişinin son değerini almakla ilgilenen birçok insan vardır ArrayList.
Tregoreg

3

Çözeltide belirtildiği gibi, eğer Listboşsa IndexOutOfBoundsException, a atılır. Daha iyi bir çözüm Optionaltürü kullanmaktır :

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

Beklediğiniz gibi, listenin son öğesi şu şekilde döndürülür Optional:

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

Ayrıca boş listelerle de incelikle ilgilenir:

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

2

Bunun yerine LinkedList kullanıyorsanız, ilk öğeye ve son öğeye just getFirst()ve ile erişebilirsiniz getLast()((size () -1 boyutundan daha temiz bir yol istiyorsanız ve (0) olsun)

uygulama

LinkedList bildirin

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

O zaman bu, istediğinizi elde etmek için kullanabileceğiniz yöntemlerdir, bu durumda bir listenin İLK ve SON öğesinden bahsediyoruz

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

Yani, o zaman kullanabilirsiniz

mLinkedList.getLast(); 

Listenin son öğesini almak için.


1

guava , son öğeyi aşağıdakilerden elde etmek için başka bir yol sağlar List:

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

verilen liste boşsa, IndexOutOfBoundsException


1
java.util.Collections#reversebunu da yapar.
RoBeaToZ

1
@RoBeaToZ, öyle, ancak orijinal listeyi yineleyerek değiştirir ve void döndürür, bu nedenle bu amaca uymaz.
pero_hero

0

ArrayList içindeki indeksleme 0'dan başladığından ve gerçek boyuttan önce bir yerden sona erdiğinden, son arraylist öğesini döndürmek için doğru ifade şöyle olacaktır:

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

Örneğin:

dizi listesinin boyutu 5 ise, size-1 = 4 son dizi öğesini döndürür.


-1

Listedeki son öğe list.size() - 1. Koleksiyon bir dizi tarafından desteklenir ve diziler 0 dizininden başlar.

Yani listedeki eleman 1 dizideki 0 dizinindedir

Listedeki öğe 2, dizideki dizin 1'de

Listedeki öğe 3, dizinin 2. dizinindedir

ve bunun gibi..


3
JohannesSchaub'ın önceki cevabına ek değer yok
Karl Richter

-3

Buna ne dersiniz .. Sınıfınızda bir yerlerde ...

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

Listenizi değiştirirseniz listIterator(), son dizinden ( size()-1sırasıyla) kullanın ve yineleyin . Tekrar başarısız olursanız, liste yapınızı kontrol edin.


-3

Yapmanız gereken tek şey Arraylist'in son değerini almak için size () kullanmaktır. Örn. ArrayList tamsayıları varsa, son değeri almak için

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

Unutmayın, bir Arraylist'teki öğelere dizin değerleri kullanılarak erişilebilir. Bu nedenle, ArrayLists genellikle öğeleri aramak için kullanılır.


4
JohannesSchaub'ın önceki cevabına ek değer yok
Karl Richter

-4

diziler boyutlarını 'uzunluk' adı verilen yerel bir değişkende saklar. "A" adlı bir dizi verildiğinde, dizin değerini bilmeden son dizine başvurmak için aşağıdakileri kullanabilirsiniz

Bir [a.length-1]

kullanacağınız bu son dizine 5 değeri atamak için:

Bir [a.length-1] '= 5;


Bu ArrayListbir dizi değil.
glee8e

-6

Akış API'sını kullanarak alternatif:

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

Son öğenin İsteğe Bağlı sonucunu verir.


-7

Kotlin'de şu yöntemi kullanabilirsiniz last:

val lastItem = list.last()

10
Ancak bu java
Jachdich

4
Kotlin'i yaratmanın arkasındaki fikirlerden biri, Java'nın biraz rahatsız edici yanlarını kapatmaktı. Bu yüzden Kotlin'i, en azından uygulamanın veri analizleri yapan kısımları için düşünmenizi öneririz.
Eerik Sven Puudist
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.