java: ArrayList - ฉันจะตรวจสอบได้อย่างไรว่ามีดัชนีอยู่หรือไม่?


111

ฉันใช้ArrayList<String>และเพิ่มข้อมูลในดัชนีเฉพาะฉันจะตรวจสอบได้อย่างไรว่ามีดัชนีเฉพาะอยู่หรือไม่

ฉันควรget()ตรวจสอบค่าหรือไม่? หรือควรรอให้มีการยกเว้น? มีวิธีอื่นอีกไหม

อัปเดต

ขอบคุณสำหรับคำตอบ แต่เนื่องจากฉันกำลังเพิ่มข้อมูลที่ดัชนีเฉพาะความยาวของรายการจึงไม่แสดงให้ฉันเห็น


2
ลองดูชุดที่เหมาะกับสิ่งที่คุณต้องการมากกว่านี้หรือไม่?
Paul Whelan

3
จากนั้นคุณจะต้องget()ตรวจสอบnull- อย่าพึ่งยกเว้น ลองใช้java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.htmlHashTableแทน
Amarghosh

สุดยอด !! ฉันจะใช้ HashTable ขอบคุณ
ufk

คำตอบ:


159

วิธีนี้arrayList.size() จะส่งคืนจำนวนรายการในรายการดังนั้นหากดัชนีมีค่ามากกว่าหรือเท่ากับดัชนีจะsize()ไม่มีอยู่

if(index >= myList.size()){
  //index not exists
}else{
 // index exists
}

10
ซึ่งควรจะ "มากกว่าหรือเท่ากับsize()" เนื่องจากเป็นดัชนีที่อิงศูนย์
McDowell

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

3
โปรดทราบว่าฉันทำเครื่องหมายคำตอบนี้ถูกต้องเป็นเพราะเจ้าของ (Amarghosh) ที่ตอบคำถามของฉันในความคิดเห็นต่อคำถามของฉัน HashTable จะตอบสนองความต้องการของฉันได้ดีขึ้นมาก
ufk

จะเป็นอย่างไรหากคุณตั้งค่ารายการในรายการอาร์เรย์ด้วย ID ของรายการ เช่น mylist.set (1, item1); mylist.set (3, item3); // ข้าม 2 ฉันเดาว่า HashMap เหมาะกับสถานการณ์นั้นมากกว่า?
yeahman

สิ่งนี้ไม่ค่อยทำให้ฉันพอใจ .. ถ้าฉันต้องการทำอะไรบางอย่างในรายการหากดัชนีมีอยู่แล้ว แต่อย่างอื่นเพื่อเตรียมมัน .. ด้วยรายการใหม่ฉันจะเริ่มต้นindex = 0และของฉันlist.size() == 0ด้วย ดังนั้นในครั้งแรกที่ฉันตรวจสอบมันจะเป็นจริงและฉันจะเตรียมรายการเพื่อทำสิ่งต่างๆ แต่ในครั้งต่อไปที่ดัชนีนั้นดัชนีของฉันจะยังคงเป็นindex = 0และตอนนี้ฉันกำลังเริ่มต้นองค์ประกอบนั้นใหม่ในรายการเมื่อฉันควรจะทำสิ่งต่างๆ ความคิดแรกคือ&&เงื่อนไขที่สองเช่นlist.get(index) == nullแต่ไม่ได้ผลคือทำไมมีคำถามเช่นนี้
roberto tomás

69

แม้ว่าคุณจะได้รับคำแนะนำมากมายเกี่ยวกับการใช้ขนาดของรายการของคุณซึ่งใช้ได้กับรายการที่มีรายการเชิงเส้น แต่ดูเหมือนจะไม่มีใครอ่านคำถามของคุณ

หากคุณเพิ่มรายการด้วยตนเองที่ดัชนีที่แตกต่างกันคำแนะนำเหล่านี้จะไม่ได้ผลเนื่องจากคุณต้องตรวจสอบดัชนีเฉพาะ

ใช้if (list.get (ดัชนี) == null)จะไม่ทำงานเช่นกันเนื่องจาก get () แสดงข้อยกเว้นแทนการคืนค่า null

ลองสิ่งนี้:

try {
    list.get( index );
} catch ( IndexOutOfBoundsException e ) {
    list.add( index, new Object() );
}

ที่นี่จะมีการเพิ่มรายการใหม่หากไม่มีดัชนี คุณสามารถปรับเปลี่ยนเพื่อทำสิ่งที่แตกต่างออกไป


2
ขอบคุณเทคนิคนี้สำหรับการทดสอบหน่วยว่ามีดัชนีอาร์เรย์หรือไม่
Noumenon

11
อย่าลืมใช้try/catchสำหรับงานประเภทนี้จะทำให้โปรแกรมของคุณช้าลง 50% หรืออาจจะมากกว่านั้น .. การตรวจสอบข้อผิดพลาดจะเพิ่มเหมือนสายรัดให้กับโค้ดที่มีอยู่เพื่อให้ทำงานช้าลง .. ดีกว่าที่จะหลีกเลี่ยงในพื้นที่วิกฤต การตรวจสอบlengthในกรณีนี้เป็นสิ่งที่ดีที่สุดที่คุณสามารถทำได้เนื่องจากindexจะมีค่าน้อยกว่าเสมอสิ่งlengthเก่าindexจะถูกเปลี่ยนไปและกลายเป็นของใหม่indexหากคุณเป็นremoveเช่นนั้นนั่นคือเหตุผลที่การตรวจสอบกฎlengthเสมอจึงใช้ได้ผล
SSpoke

1
@Spoke ... ในขณะที่ฉันเห็นด้วยลอง / จับยังห่างไกลจากคำตอบที่ 'ดี' จะแก้ไขปัญหาเมื่อรายการเบาบางลง ฉันชอบคำแนะนำในการใช้อาร์เรย์: Object [] ary; ด้านล่างหรือแฮช
จะ

12

นี่คือสิ่งที่คุณต้องการ ...

public boolean indexExists(final List list, final int index) {
    return index >= 0 && index < list.size();
}

ทำไมไม่ใช้อาร์เรย์เก่าธรรมดา การเข้าถึงรายการที่จัดทำดัชนีเป็นกลิ่นรหัสที่ฉันคิด


3
ไม่เสมอไปเนื่องจากเขาอาจต้องการให้ ArrayList เติบโตขึ้นเมื่อเวลาผ่านไปและอาร์เรย์ไม่สามารถทำได้
Coyote21

7

โดยปกติฉันจะตรวจสอบว่าดัชนีมีค่าน้อยกว่าขนาดอาร์เรย์หรือไม่

if (index < list.size()) {
    ...
}

หากคุณกังวลว่าดัชนีจะเป็นค่าลบให้ใช้ดังต่อไปนี้

if (index >= 0 && index < list.size()) {
    ...
}

1
สิ่งนี้ให้คุณค่าเหนือคำตอบที่ยอมรับเมื่อหลายปีก่อนอย่างไร
Basil Bourque

2
ฉันเดาว่าในมุมมองของคุณมันไม่ได้ให้คุณค่าใด ๆ แต่ฉันเห็นความคิดเห็นของ roberto tomásเกี่ยวกับคำตอบที่ได้รับการยอมรับโดยถือว่าเขาไม่ค่อยเข้าใจคำตอบที่ยอมรับ ลองดูสิ "ด้วยรายการใหม่ฉันจะเริ่มต้นที่ index = 0 และ list.size () == 0 ของฉันด้วยดังนั้นในครั้งแรกที่ฉันตรวจสอบมันจะเป็นจริง" ฉันตัดสินใจโพสต์คำตอบแยกต่างหากเพื่อช่วย ความสับสนในอนาคต
AamirR

5

เกี่ยวกับการอัปเดตของคุณ (ซึ่งอาจเป็นคำถามอื่น) คุณควรใช้อาร์เรย์ของวัตถุเหล่านี้แทน ArrayList ดังนั้นคุณสามารถตรวจสอบค่า null ได้โดยง่าย:

Object[] array = new Object[MAX_ENTRIES];
..
if ( array[ 8 ] == null ) {
   // not available
}
else {
   // do something
}

ปฏิบัติที่ดีที่สุด

หากคุณไม่มีรายการหลายร้อยรายการในอาร์เรย์ของคุณคุณควรพิจารณาจัดเป็นชั้นเรียนเพื่อกำจัดเลขวิเศษ 3,8 เป็นต้น

การควบคุมโฟลว์โดยใช้ข้อยกเว้นเป็นการปฏิบัติที่ไม่ดี


2
หากไม่มีอาร์เรย์ [8] คุณจะพบ ArrayIndexOutOfBoundException
Nitesh Kumar Anand

4

เนื่องจากjava-9มีวิธีมาตรฐานในการตรวจสอบว่าดัชนีเป็นของอาร์เรย์หรือไม่ - Objects # checkIndex () :

List<Integer> ints = List.of(1,2,3);
System.out.println(Objects.checkIndex(1,ints.size())); // 1
System.out.println(Objects.checkIndex(10,ints.size())); //IndexOutOfBoundsException

of()วิธีการนี้ยังมีการเพิ่มในJava 9 ชั้นเรียนรายการ : docs.oracle.com/javase/9/docs/api/java/util/List.html#of--
Orici

3

คุณสามารถตรวจสอบขนาดของArrayListโดยใช้size()วิธีการ สิ่งนี้จะคืนค่าดัชนีสูงสุด +1


2

วิธีง่ายๆในการทำสิ่งนี้:

try {
  list.get( index ); 
} 
catch ( IndexOutOfBoundsException e ) {
  if(list.isEmpty() || index >= list.size()){
    // Adding new item to list.
  }
}

1

ทดสอบอย่างรวดเร็วและสกปรกว่ามีดัชนีอยู่หรือไม่ ในการใช้งานของคุณแทนที่รายการด้วยรายการของคุณที่คุณกำลังทดสอบ

public boolean hasIndex(int index){
    if(index < list.size())
        return true;
    return false;
}

หรือสำหรับ 2 มิติ ArrayLists ...

public boolean hasRow(int row){
    if(row < _matrix.size())
        return true;
    return false;
}

1
รายการไม่ได้.lengthก็มีlist.size()แต่มันก็ไม่ใช่เรื่องใหญ่ผมกรูขึ้นเช่นนี้ตลอดเวลาฮ่าฮ่าฉันพึ่งพาคอมไพเลอร์จะแนะนำฉันในที่หนึ่ง คุณอาจนึกถึงอาร์เรย์ดั้งเดิม
SSpoke

1
ขอบคุณที่จับได้ ความสำคัญของตู้คอนเทนเนอร์สามารถลืมได้ง่าย
t3dodson

0

หากดัชนีของคุณมีขนาดน้อยกว่าขนาดของรายการของคุณแสดงว่ามีอยู่อาจมีnullค่า หากดัชนีใหญ่กว่าคุณสามารถโทรensureCapacity() ให้สามารถใช้ดัชนีนั้นได้

หากคุณต้องการตรวจสอบว่าค่าดัชนีของคุณเป็นnullหรือไม่โทรget()


1
การเรียก sureCapacity (int) จะไม่เพิ่มขนาดของรายการ แต่เป็นความจุเท่านั้น เช่น "ขนาดที่เป็นไปได้" ดังนั้นการค้นหาดัชนีนอกขอบเขตจะยังคงล้มเหลว
Adamski

นอกจากนี้ทำไมต้องเรียก sureCapacity (int) เลย? อาจเป็นการดำเนินการที่มีราคาแพงอย่างไม่น่าเชื่อหากตัวอย่างเช่นขนาดปัจจุบันของรายการคือ 5 และคุณต้องการกำหนดมูลค่าของรายการ #: 100,000,000
Adamski

ฉันหมายความว่าดัชนีที่น้อยกว่า size () จะมีอยู่เสมอซึ่งนั่นคือ> = size () ไม่และไม่มีใครใช้ (== call set ()) จนกว่ารายการจะใหญ่พอ การเรียกว่า sureCapacity ไม่เพียงพอแน่นอนเราต้องเปลี่ยนขนาดโดยการเพิ่มองค์ประกอบ
Dmitry

คำอธิบายที่ไม่ถูกต้องเกี่ยวกับสิ่งที่ sureCapacity (int) ทำจริง ไม่มีอะไรกับขนาด ArrayList
Mohsen

0

คุณสามารถตรวจสอบขนาดของอาร์เรย์ได้

package sojava;
import java.util.ArrayList;

public class Main {
    public static Object get(ArrayList list, int index) {
        if (list.size() > index) { return list.get(index); }
        return null;
    }

    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(""); list.add(""); list.add("");        
        System.out.println(get(list, 4));
        // prints 'null'
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.