วิธีรับค่าสุดท้ายของ ArrayList


597

ฉันจะรับค่าสุดท้ายของ ArrayList ได้อย่างไร

ฉันไม่รู้ดัชนีสุดท้ายของ ArrayList


164
ฉันตอบคำถามนี้เพราะฉันสงสัยว่าทำไมไม่มีวิธีเช่น: getLastItem () และมาดูว่ามีคำตอบไหม list.size () - 1 ไม่สวย
Nuno Gonçalves

2
@ NunoGonçalvesคุณสามารถคลาสย่อยได้เสมอ!
ทิม

12
คุณสามารถใช้ LinkedList ซึ่งมีเมธอดอยู่เสมอgetLast()
ssedano

6
รายการที่เชื่อมโยงจะเพิ่มทั้งจำนวนของค่าใช้จ่าย ใช้ Guava ดังแสดงด้านล่าง: lastElement = Iterables.getLast (iterableList); หรือเพียงแค่จัดทำดัชนีการเรียก get () พร้อม size () - 1 มันไม่น่าเกลียดเมื่อเทียบกับการใช้รายการที่เชื่อมโยงเมื่อไม่ต้องการ คำเตือนทั่วไปใช้กับเงื่อนไขข้อยกเว้น - ดู ArrayList javadoc
RichieHH

10
การใช้ list.size () -1 ไม่สวย แต่การใช้ API ของบุคคลที่สามเพียงแค่นี้ก็แย่ลง
Javo

คำตอบ:


692

ต่อไปนี้เป็นส่วนหนึ่งของListอินเทอร์เฟซ (ซึ่ง ArrayList ใช้):

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

Eเป็นประเภทองค์ประกอบ ถ้ารายการว่างเปล่าพ่นget IndexOutOfBoundsExceptionคุณสามารถค้นหาเอกสาร API ทั้งหมดที่นี่


5
สิ่งนี้จะทำให้เกิดการซ้ำของรายการหรือไม่ ดูเหมือนจะไม่มีประสิทธิภาพสำหรับฉัน ฉันมาจาก C ++ ซึ่งมีเมธอด front () และ back () จริง ๆ ในอ็อบเจกต์ list ที่ถูกนำไปใช้ภายในโดยอ้างอิงจาก head และ tail มีกลไกที่คล้ายคลึงกันใน Java หรือไม่
เบรดี้

26
จะไม่ทำงาน เกิดอะไรขึ้นถ้ารายการว่าง list.size () จะกลับ 0 และคุณจะจบลงด้วย list.get (-1);
FRR

18
@feresr huh เขาต้องการรับค่าสุดท้ายในรายการ แน่นอนว่าขนาดนั้น () คือ> 0 ซึ่งจะเป็นจริงสำหรับการใช้งานทุกประเภท การอ่านจนจบจะช่วยประหยัดเวลาที่คุณต้องการในการเขียนความคิดเห็นและเวลาตอบคำถาม :) คำตอบของฉันบอกว่าท้ายที่สุด"ถ้ารายการว่างเปล่าให้โยนดัชนี IndexOutOfBoundsException"
Johannes Schaub - litb

16
@Brady จะไม่ทำให้เกิดการวนซ้ำ O (n) สำหรับ ArrayList เนื่องจากคุณสามารถเดาได้ว่ามันได้รับการสนับสนุนจากอาร์เรย์ ดังนั้นการได้รับอย่างง่าย (<index>) เพียงแค่ส่งผลให้มีการดึงค่าคงที่จากอาร์เรย์ (แหล่งที่มาของ JDK ยืนยันสิ่งนี้) สำหรับการใช้งานรายการอื่น ๆ สิ่งนี้ไม่รับประกันเช่น LinkedList มีเมธอด getLast () ซึ่งเป็นเวลาคงที่
ปีเตอร์

9
ฉันไม่สามารถเข้าใจว่าทำไมพวกเขาตัดสินใจที่จะใช้ที่ง่ายlastElement()วิธีการของพวกเขาแต่ไม่ได้สำหรับVector ArrayListเกิดอะไรขึ้นกับความไม่สอดคล้องนั้น?
Stefan Dimitrov

211

ไม่มีวิธีที่สวยงามในวานิลลาชวา

Google Guava

Google ฝรั่งห้องสมุดเป็นที่ดี - ตรวจสอบของพวกเขาในชั้นเรียนIterables วิธีนี้จะโยนNoSuchElementExceptionถ้ารายการว่างเปล่าเมื่อเทียบ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);

3
คุณรู้หรือไม่ว่าวิธีนี้ใช้การเดินเชิงเส้นผ่านรายการเพื่อค้นหาองค์ประกอบสุดท้ายหรือไม่?
BillMan

5
@BillMan ในกรณีของ HashSet ใช่ในกรณีของ ArrayList no
Simon

6
คุณควรเพิ่มการIterables.getLastตรวจสอบว่าRandomAccessมีการใช้งานหรือไม่และหากมีการเข้าถึงรายการใน O (1)
Karl Richter

1
แทนที่จะOptionคุณสามารถใช้พื้นเมือง OptionalJava มันจะสะอาดlastElement = Optional.ofNullable(lastElementRaw);ขึ้นอีกหน่อย: .
ผู้ช่วยตัวเล็ก

186

สิ่งนี้ควรทำ:

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

29
ไม่มีวิธีที่ทันสมัยในการทำเช่นนี้หรือไม่? : /
kommradHomer

6
อย่างน้อยคุณก็ควรจะสาธิตให้เห็น ...
Antony Stubbs

มันเล็กเกินไปที่จะระบุว่าข้างต้นไม่ได้กำหนด / ส่งคืนอะไร?
Brian Agnew

หาก ArrayList มีเพียงหนึ่งเร็กคอร์ดก็จะมีข้อยกเว้นเกิดขึ้น อะไรจะแก้ปัญหาได้?
hasnain_ahmad

2
@hasnain_ahmad เมื่อ ArraList มี 1 องค์ประกอบมันทำงานอย่างถูกต้องคุณควรกังวลเกี่ยวกับ ArrayList ที่ไม่ได้กำหนดค่าเริ่มต้นและ ArrayList ที่มีค่าศูนย์ และคำตอบนี้จัดการกับทั้งสองกรณี
Farid

27

ฉันใช้คลาส 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();
  }
}

8
เพียงแค่ใช้ฝรั่ง ไม่ต้องคิดค้นใหม่
คลิกโหวต

15
@ClickUpvote การใช้ Guava สำหรับวิธีการเล็ก ๆ เพียงวิธีเดียวในหลาย ๆ กรณีเป็นการ overkill คำตอบของฉันคือสำหรับคนที่กำลังมองหาวิธีการแก้ปัญหา Java วานิลลา หากคุณใช้ Guava อยู่ในโครงการของคุณแล้วโปรดดูคำตอบอื่น ๆ สำหรับโซลูชันที่ใช้ Guava
user11153

5
หากคุณไม่ใช้ฝรั่งคุณจะต้องเขียนคลาสยูทิลิตี้มากมายเช่นนี้
คลิกโหวต

6
บางครั้งการได้รับอนุญาตให้เพิ่มห้องสมุดบุคคลที่สามอาจมีส่วนเกี่ยวข้องมากกว่าการเพิ่มคลาส Java ดั้งเดิม ตัวอย่างเช่นสัญญาของรัฐบาลที่ จำกัด และกลั่นกรองห้องสมุดบุคคลที่สาม
เดฟจา

2
isEmptyไม่ตรวจสอบว่ารายการว่างเปล่าหรือไม่และควรเป็นเช่นนั้นisNullOrEmptyและไม่ใช่ส่วนหนึ่งของคำถาม - ไม่ว่าคุณจะพยายามปรับปรุงชุดคำตอบหรือคุณมีคลาสยูทิลิตี้ให้คุณ (ซึ่งเป็นการประดิษฐ์ใหม่)
Karl Richter

10

size()วิธีการส่งกลับจำนวนขององค์ประกอบในแบบ ArrayList ค่าดัชนีขององค์ประกอบ0ผ่าน(size()-1)ดังนั้นคุณจะใช้myArrayList.get(myArrayList.size()-1)เพื่อดึงองค์ประกอบสุดท้าย



5

หากคุณสามารถสลับออกArrayListสำหรับซึ่งมีวิธีการอำนวยความสะดวกเช่นArrayDequeremoveLast


1
ซึ่งหมายความว่าอย่างน้อยต้นทุนเชิงเส้นเมื่อเปรียบเทียบกับค่าใช้จ่ายคงที่สำหรับการเข้าถึงโดยตรง
Karl Richter

@KarlRichter ใช่ สิ่งนี้สอดคล้องกับการขาดวิธีการเช่นรับ (int) ในอินเทอร์เฟซของ ArrayDeque นี่คือสิ่งที่ฉันตั้งใจจะแนะนำโดย "ถ้าคุณทำได้"; หากรายการไม่ถูกเข้าถึงโดยดัชนีบางทีอาจไม่จำเป็นต้องเป็นรายการ
John Glassmyer

5

ไม่มีเป็นสง่างามวิธีการรับองค์ประกอบสุดท้ายของรายการในจาวา (เมื่อเทียบกับเช่นitems[-1]ในหลาม)

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


ฉันไม่เห็น "ข้อบกพร่องการออกแบบ" ที่นี่สิ่งที่คุณนำมาใช้เป็นกรณีการใช้งานที่หายากซึ่งไม่คุ้มค่าที่จะเพิ่มเข้าไปในListอินเทอร์เฟซ เหตุใดคุณต้องการเรียกวิธีการส่งคืนรายการถ้าคุณสนใจเฉพาะองค์ประกอบสุดท้าย ฉันจำไม่ได้ว่าเคยเห็นมาก่อนเลย
Dorian Gray

1
@DorianGray การอ่านองค์ประกอบสุดท้ายจากรายการเป็นการดำเนินการที่ใช้กันทั่วไปและlist.get(list.size()-1)เป็นตัวอย่างขั้นต่ำที่แสดงถึงปัญหา ฉันยอมรับว่าตัวอย่าง "ขั้นสูง" อาจเป็นที่ถกเถียงกันและอาจเป็นกรณีที่ขอบฉันแค่ต้องการแสดงให้เห็นว่าปัญหาสามารถเผยแพร่ต่อไปได้อย่างไร สมมติว่าคลาสของsomeObjectเป็นคนต่างด้าวมาจากห้องสมุดภายนอก
Tregoreg

ฉันไม่เห็นที่นี่เป็นเรื่องธรรมดาและถ้าเป็นเช่นนั้นคุณควรใช้ArrayDequeแทน
Dorian Gray

@DorianGray คำถามนี้มีจำนวนมากของ upvotes ArrayListและมุมมองเพื่อให้มีจำนวนมากของผู้ที่สนใจในการรับค่าสุดท้ายของ
Tregoreg

3

ตามที่ระบุในการแก้ปัญหาถ้า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;

2

หากคุณใช้ LinkedList แทนคุณสามารถเข้าถึงองค์ประกอบแรกและองค์ประกอบสุดท้ายได้เพียงgetFirst()และgetLast()(ถ้าคุณต้องการวิธีที่สะอาดกว่าขนาด () -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(); 

เพื่อรับองค์ประกอบสุดท้ายของรายการ


1

ฝรั่งให้วิธีอื่นในการรับองค์ประกอบสุดท้ายจากList:

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

หากรายการที่ให้ไว้ว่างเปล่ามันจะส่ง IndexOutOfBoundsException


1
java.util.Collections#reverseทำเช่นกัน
RoBeaToZ

1
@RoBeaToZ มันทำ แต่เปลี่ยนรายการเดิมโดยวนซ้ำและส่งคืนโมฆะดังนั้นจึงไม่ถือว่าเหมาะสมสำหรับวัตถุประสงค์นี้
pero_hero

0

เนื่องจากการจัดทำดัชนีใน ArrayList เริ่มต้นจาก 0 และสิ้นสุดที่เดียวก่อนขนาดจริงดังนั้นคำสั่งที่ถูกต้องเพื่อส่งกลับองค์ประกอบอาร์เรย์สุดท้ายจะเป็น:

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

ตัวอย่างเช่น:

ถ้าขนาดของรายการอาเรย์คือ 5 ดังนั้นขนาด -1 = 4 จะส่งคืนองค์ประกอบอาเรย์สุดท้าย


-1

list.size() - 1รายการสุดท้ายในรายการเป็น คอลเลกชันได้รับการสนับสนุนโดยอาร์เรย์และอาร์เรย์เริ่มต้นที่ดัชนี 0

ดังนั้นองค์ประกอบ 1 ในรายการอยู่ที่ดัชนี 0 ในอาร์เรย์

องค์ประกอบที่ 2 ในรายการอยู่ที่ดัชนี 1 ในอาร์เรย์

องค์ประกอบ 3 ในรายการอยู่ที่ดัชนี 2 ในอาร์เรย์

และอื่น ๆ ..


3
ไม่มีค่าเพิ่มเติมสำหรับคำตอบก่อนหน้าของ @ JohannesSchaub
Karl Richter

-3

แล้วเรื่องนี้ .. อยู่ที่ไหนในชั้นเรียนของคุณ ...

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

หากคุณแก้ไขรายการของคุณให้ใช้listIterator()และทำซ้ำจากดัชนีล่าสุด (นั่นคือsize()-1ตามลำดับ) หากคุณล้มเหลวอีกครั้งให้ตรวจสอบโครงสร้างรายการของคุณ


-3

สิ่งที่คุณต้องทำคือใช้ขนาด () เพื่อรับค่าสุดท้ายของ Arraylist สำหรับอดีต ถ้าคุณ ArrayList ของจำนวนเต็มดังนั้นเมื่อต้องการรับค่าสุดท้ายคุณจะต้อง

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

โปรดจำไว้ว่าองค์ประกอบใน Arraylist สามารถเข้าถึงได้โดยใช้ค่าดัชนี ดังนั้น ArrayLists จึงถูกใช้เพื่อค้นหารายการ


4
ไม่มีค่าเพิ่มเติมสำหรับคำตอบก่อนหน้าของ @ JohannesSchaub
Karl Richter

-4

อาร์เรย์เก็บขนาดไว้ในตัวแปรท้องถิ่นที่เรียกว่า 'length' รับอาร์เรย์ชื่อ "a" คุณสามารถใช้สิ่งต่อไปนี้เพื่ออ้างอิงดัชนีล่าสุดโดยไม่ทราบค่าดัชนี

a [a.length-1]

เพื่อกำหนดค่า 5 ให้กับดัชนีล่าสุดนี้คุณจะใช้:

a [a.length-1] = 5;


นี่ArrayListไม่ใช่อาร์เรย์
glee8e

-6

ทางเลือกโดยใช้ Stream API:

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

ผลลัพธ์ในตัวเลือกขององค์ประกอบสุดท้าย


-7

ใน Kotlin คุณสามารถใช้วิธีการlast:

val lastItem = list.last()

10
นี่คือ java แต่
Jachdich

4
หนึ่งในความคิดที่อยู่เบื้องหลังการสร้าง Kotlin คือการครอบคลุมด้านที่ไม่สะดวกของ Java ดังนั้นฉันคิดว่ามันสมเหตุสมผลที่จะแนะนำให้พิจารณา Kotlin อย่างน้อยก็สำหรับส่วนของแอปพลิเคชันที่ใช้วิเคราะห์ข้อมูล
Eerik Sven Puudist
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.