Cara mendapatkan nilai terakhir dari ArrayList

597

Bagaimana saya bisa mendapatkan nilai terakhir dari ArrayList?

Saya tidak tahu indeks terakhir dari ArrayList.

Jessy
sumber
164
Saya mengangkat pertanyaan ini, karena saya bertanya-tanya mengapa tidak ada metode seperti: getLastItem () dan datang untuk melihat apakah ada jawaban. list.size () - 1 tidak cantik.
Nuno Gonçalves
2
@ NunoGonçalves Anda selalu dapat mensubklasifikasikannya!
Tim
12
Anda selalu dapat menggunakan LinkedList yang memiliki metodegetLast()
ssedano
6
Daftar yang ditautkan itu menambah banyak tumpukan overhead. Gunakan Guava seperti yang ditunjukkan di bawah ini: lastElement = Iterables.getLast (iterableList); ATAU cukup indeks panggilan get () dengan size () - 1. Tidak seburuk itu dibandingkan dengan menggunakan daftar yang ditautkan saat tidak diperlukan. Peringatan biasa berlaku terkait kondisi pengecualian - lihat javadoc ArrayList.
RichieHH
10
Menggunakan list.size () -1 tidak cantik, tetapi menggunakan API pihak ke-3 hanya untuk ini lebih buruk
Javo

Jawaban:

692

Berikut ini adalah bagian dari Listantarmuka (yang mengimplementasikan ArrayList):

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

Eadalah tipe elemen. Jika daftar kosong, getlemparkan a IndexOutOfBoundsException. Anda dapat menemukan seluruh dokumentasi API di sini .

Johannes Schaub - litb
sumber
5
Apakah ini akan menyebabkan iterasi daftar? Bagi saya itu tidak efisien. Saya berasal dari C ++, di mana ada sebenarnya depan () dan belakang () metode pada objek daftar, yang diimplementasikan secara internal dengan referensi kepala dan ekor. Apakah ada mekanisme serupa di Jawa?
Brady
26
Tidak akan bekerja bagaimana jika daftar itu kosong, list.size () akan mengembalikan 0. dan Anda akan berakhir dengan list.get (-1);
FRR
18
@feresr ya. Dia ingin mendapatkan nilai terakhir dalam daftar. Tentu saja itu menyiratkan bahwa ukuran () adalah> 0. Itu akan berlaku untuk segala jenis implementasi. Membaca sampai akhir akan menghemat waktu yang Anda butuhkan untuk menulis komentar dan waktu saya untuk menjawab :) Jawaban saya mengatakan di akhir "Jika daftar itu kosong, dapatkan melempar IndexOutOfBoundsException"
Johannes Schaub - litb
16
@ Brady itu tidak akan menyebabkan iterasi O (n) untuk ArrayList, karena seperti yang bisa Anda tebak, itu didukung oleh sebuah array. Jadi get sederhana (<index>) hanya menghasilkan waktu konstan yang diambil dari array. (Sumber JDK mengkonfirmasi ini) Untuk implementasi daftar lainnya, ini tidak dijamin, jadi misalnya, LinkedList memiliki metode getLast () yang merupakan waktu konstan.
Peter
9
Saya tidak mengerti mengapa mereka memutuskan untuk menerapkan lastElement()metode sederhana untuk mereka Vectortetapi tidak untuk ArrayList. Ada apa dengan inkonsistensi itu?
Stefan Dimitrov
211

Tidak ada cara yang elegan di vanilla Java.

Google Jambu

The Google Jambu perpustakaan besar - memeriksa mereka Iterableskelas . Metode ini akan melempar NoSuchElementExceptionjika daftar kosong, sebagai lawan dari IndexOutOfBoundsException, seperti dengan size()-1pendekatan khas - saya menemukan NoSuchElementExceptionjauh lebih bagus, atau kemampuan untuk menentukan default:

lastElement = Iterables.getLast(iterableList);

Anda juga dapat memberikan nilai default jika daftar kosong, bukan pengecualian:

lastElement = Iterables.getLast(iterableList, null);

atau, jika Anda menggunakan Opsi:

lastElementRaw = Iterables.getLast(iterableList, null);
lastElement = (lastElementRaw == null) ? Option.none() : Option.some(lastElementRaw);
Antony Stubbs
sumber
3
Apakah Anda tahu jika ini metode ini melakukan linear berjalan melalui daftar untuk menemukan elemen terakhir?
BillMan
5
@ BillMan Dalam kasus HashSet ya, dalam kasus ArrayList no.
Simon
6
Anda harus menambahkan Iterables.getLastcek itu apakah RandomAccessditerapkan dan karenanya jika mengakses item dalam O (1).
Karl Richter
1
Alih-alih Option, Anda bisa menggunakan Java asli Optional. Ini juga akan menjadi sedikit lebih bersih: lastElement = Optional.ofNullable(lastElementRaw);.
Little Helper
186

ini harus dilakukan:

if (arrayList != null && !arrayList.isEmpty()) {
  T item = arrayList.get(arrayList.size()-1);
}
Henrik Paul
sumber
29
Apakah tidak ada cara yang ramping untuk melakukannya? : /
kommradHomer
6
Anda mungkin setidaknya harus menunjukkan menugaskan itu ... ArrayList.get adalah efek samping gratis.
Antony Stubbs
Apakah terlalu kecil untuk menunjukkan hal di atas tidak menetapkan / mengembalikan apa pun?
Brian Agnew
Jika ArrayList hanya memiliki satu catatan maka ada pengecualian terjadi. Apa yang akan menjadi solusinya?
hasnain_ahmad
2
@hasnain_ahmad, ketika ArraList memiliki 1 elemen berfungsi dengan baik, Anda harus khawatir tentang ArrayList dan ArrayList yang tidak diinisialisasi dengan nol catatan. Dan jawaban ini menangani kedua kasus
Farid
27

Saya menggunakan kelas utilitas mikro untuk mendapatkan elemen terakhir (dan pertama) dari daftar:

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

Sedikit lebih fleksibel:

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();
  }
}
pengguna11153
sumber
8
Cukup gunakan jambu biji. Jangan menciptakan kembali
Klik Suara
15
@ClickUpvote Menggunakan Guava hanya untuk satu metode kecil dalam banyak kasus adalah berlebihan. Jawaban saya adalah untuk orang yang mencari solusi vanilla Java . Jika Anda sudah menggunakan Jambu Biji di proyek Anda, lihat jawaban lain untuk solusi berbasis Jambu.
user11153
5
Jika Anda tidak menggunakan jambu biji, Anda akhirnya menulis banyak kelas utilitas seperti ini.
Klik Suara
6
Kadang-kadang mendapatkan izin untuk menambahkan perpustakaan pihak ketiga bisa lebih banyak terlibat daripada menambahkan kelas Java asli tunggal. Misalnya, kontrak pemerintah di mana mereka membatasi dan menyaring perpustakaan pihak ketiga.
Dave Jarvis
2
isEmptytidak memeriksa apakah daftar itu kosong dan dengan demikian seharusnya isNullOrEmptydan itu bukan bagian dari pertanyaan - apakah Anda mencoba untuk meningkatkan set jawaban atau Anda memberi Anda kelas utilitas (yang merupakan penemuan ulang).
Karl Richter
10

The size()Metode mengembalikan jumlah elemen dalam ArrayList. Nilai indeks elemen 0melalui (size()-1), jadi Anda akan gunakan myArrayList.get(myArrayList.size()-1)untuk mengambil elemen terakhir.

Ken Paul
sumber
6

Menggunakan lambdas:

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

Tidak ada cara yang elegan untuk mendapatkan elemen terakhir dari daftar di Jawa (dibandingkan dengan misalnya items[-1]dengan Python).

Anda harus menggunakan list.get(list.size()-1).

Ketika bekerja dengan daftar yang diperoleh dengan panggilan metode yang rumit, solusinya terletak pada variabel sementara:

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

Ini adalah satu-satunya pilihan untuk menghindari versi yang jelek dan sering mahal atau bahkan tidak berfungsi:

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

Akan lebih baik jika perbaikan untuk cacat desain ini diperkenalkan ke Java API.

Tregoreg
sumber
Saya tidak melihat "desain cacat" di sini, apa yang Anda bawa adalah kasus penggunaan yang jarang yang tidak layak ditambahkan ke Listantarmuka. Mengapa Anda ingin memanggil metode yang mengembalikan Daftar, jika Anda hanya tertarik pada elemen terakhir? Saya tidak ingat pernah melihat itu sebelumnya.
Dorian Grey
1
@DorianGray Membaca elemen terakhir dari daftar adalah operasi yang cukup umum dan list.get(list.size()-1)merupakan contoh minimal yang menunjukkan masalah. Saya setuju bahwa contoh "lanjutan" mungkin kontroversial dan mungkin kasus tepi, saya hanya ingin menunjukkan bagaimana masalah ini dapat menyebar lebih lanjut. Mari kita asumsikan bahwa kelasnya someObjectadalah asing, berasal dari perpustakaan eksternal.
Tregoreg
Saya tidak melihat di mana ini cukup umum, dan jika itu, sebaiknya Anda gunakan ArrayDeque.
Dorian Grey
@DorianGray Pertanyaan ini memiliki banyak upvotes dan pandangan, jadi ada banyak orang yang tertarik untuk mendapatkan nilai terakhir dari sebuah ArrayList.
Tregoreg
5

Jika Anda bisa, tukar keluar ArrayListuntuk ArrayDeque, yang memiliki metode nyaman seperti removeLast.

John Glassmyer
sumber
1
Ini berarti setidaknya biaya linear dibandingkan dengan biaya konstan untuk akses langsung, tetapi layak disebutkan.
Karl Richter
@KarlRichter Ya. Ini sesuai dengan tidak adanya metode seperti get (int) di antarmuka ArrayDeque. Inilah yang saya maksudkan dengan "Jika Anda bisa"; jika daftar tidak diakses oleh indeks, maka mungkin daftar itu tidak perlu.
John Glassmyer
3

Seperti yang dinyatakan dalam solusi, jika Listkosong maka IndexOutOfBoundsExceptiondilemparkan. Solusi yang lebih baik adalah dengan menggunakan Optionaltipe:

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

Seperti yang Anda harapkan, elemen terakhir dari daftar dikembalikan sebagai Optional:

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

Itu juga berurusan dengan anggun dengan daftar kosong juga:

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

Jika Anda menggunakan LinkedList, Anda dapat mengakses elemen pertama dan terakhir dengan adil getFirst()dan getLast()(jika Anda menginginkan cara yang lebih bersih daripada ukuran () -1 dan dapatkan (0))

Penerapan

Deklarasikan LinkedList

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

Maka ini adalah metode yang dapat Anda gunakan untuk mendapatkan apa yang Anda inginkan, dalam hal ini kita berbicara tentang elemen PERTAMA dan TERAKHIR daftar

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

Jadi, bisa Anda gunakan

mLinkedList.getLast(); 

untuk mendapatkan elemen terakhir dari daftar.

Gastón Saillén
sumber
1

jambu biji menyediakan cara lain untuk mendapatkan elemen terakhir dari List:

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

jika daftar yang disediakan kosong itu melempar IndexOutOfBoundsException

pero_hero
sumber
1
java.util.Collections#reversemelakukannya juga.
RoBeaToZ
1
@RoBeaToZ, tetapi ia mengubah daftar asli dengan mengulanginya dan mengembalikan batal, sehingga tidak dianggap cocok untuk tujuan ini.
pero_hero
0

Karena pengindeksan di ArrayList dimulai dari 0 dan berakhir di satu tempat sebelum ukuran sebenarnya, maka pernyataan yang benar untuk mengembalikan elemen arraylist terakhir adalah:

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

Sebagai contoh:

jika ukuran daftar array adalah 5, maka size-1 = 4 akan mengembalikan elemen array terakhir.

shravyaverma
sumber
-1

Item terakhir dalam daftar adalah list.size() - 1. Koleksi didukung oleh array dan array mulai dari indeks 0.

Jadi elemen 1 dalam daftar adalah pada indeks 0 dalam array

Elemen 2 dalam daftar adalah pada indeks 1 dalam array

Elemen 3 dalam daftar adalah pada indeks 2 dalam array

dan seterusnya..

Program Mirco
sumber
3
tidak ada nilai tambahan untuk jawaban @ JohannesSchaub sebelumnya
Karl Richter
-3

Bagaimana dengan ini .. Di suatu tempat di kelas Anda ...

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;
    }
rokrfellr
sumber
-3

Jika Anda memodifikasi daftar Anda, maka gunakan listIterator()dan lakukan iterate dari indeks terakhir ( size()-1masing - masing). Jika Anda gagal lagi, periksa struktur daftar Anda.

dae
sumber
-3

Yang perlu Anda lakukan adalah menggunakan size () untuk mendapatkan nilai terakhir dari Arraylist. Misalnya jika Anda ArrayList bilangan bulat, maka untuk mendapatkan nilai terakhir Anda harus

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

Ingat, elemen dalam Arraylist dapat diakses menggunakan nilai indeks. Karenanya, ArrayLists umumnya digunakan untuk mencari item.

pengguna4660857
sumber
4
tidak ada nilai tambahan untuk jawaban @ JohannesSchaub sebelumnya
Karl Richter
-4

array menyimpan ukurannya dalam variabel lokal yang disebut 'panjang'. Diberikan array bernama "a" Anda bisa menggunakan yang berikut untuk referensi indeks terakhir tanpa mengetahui nilai indeks

a [a.length-1]

untuk menetapkan nilai 5 pada indeks terakhir ini, Anda akan menggunakan:

a [a.length-1] = 5;

closeab
sumber
Ini ArrayListbukan array.
glee8e
-6

Alternatif menggunakan Stream API:

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

Menghasilkan Opsional dari elemen terakhir.

Terran
sumber
-7

Di Kotlin, Anda dapat menggunakan metode ini last:

val lastItem = list.last()
Ollie
sumber
10
Namun ini adalah java
Jachdich
4
Salah satu ide di balik penciptaan Kotlin adalah untuk menutupi sisi kecil Jawa yang tidak nyaman. Jadi saya pikir masuk akal untuk merekomendasikan mempertimbangkan Kotlin, setidaknya untuk bagian aplikasi yang melakukan analisis data.
Eerik Sven Puudist