java: ArrayList - jak mogę sprawdzić, czy indeks istnieje?


111

Używam ArrayList<String>i dodaję dane do określonych indeksów, jak mogę sprawdzić, czy określony indeks istnieje?

Czy powinienem po prostu get()sprawdzić wartość? Czy powinienem poczekać na wyjątek? Czy jest inny sposób?

Aktualizacja

Dziękuję za odpowiedzi, ale ponieważ dodam tylko rzeczy w określonych indeksach, długość listy nie pokaże mi, które są dostępne.


2
Rzuć okiem na zestaw, być może bardziej pasuje do tego, czego potrzebujesz?
Paul Whelan,

3
Wtedy będziesz musiał get()sprawdzić null- nie polegaj jednak na wyjątkach. Rozważ użycie HashTablezamiast tego java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html
Amarghosh

niesamowite!!
Użyję

Odpowiedzi:


159

Metoda arrayList.size() zwraca liczbę elementów na liście - więc jeśli indeks jest większy lub równy size(), to nie istnieje.

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

10
Powinno to być „większe lub równe size()”, ponieważ jest to indeks zaczynający się od zera.
McDowell

1
Warto również wspomnieć, że aby uczynić to atomowym, prawdopodobnie powinieneś wykonać sprawdzenie size () i odpowiednie warunkowe przeglądanie indeksów, jednocześnie blokując listę.
Adamski

3
proszę zauważyć, że zaznaczam tę odpowiedź jako poprawną, ponieważ właściciel (Amarghosh) odpowiedział na moje pytanie w komentarzu do mojego pytania. HashTable znacznie lepiej zaspokoi moje potrzeby.
ufk

co się stanie, jeśli ustawiasz elementy na liście arraylistycznej z identyfikatorem elementu? dawny. mylist.set (1, pozycja1); mylist.set (3, pozycja3); // pomijam 2 Myślę, że HashMap jest bardziej odpowiedni dla tego scenariusza?
yeahman,

nie do końca mnie to satysfakcjonuje ... jeśli chcę coś zrobić na liście, jeśli indeks już tam jest, ale poza tym, aby go przygotować ... z nową listą, od której zacznę, index = 0i moją list.size() == 0też. więc za pierwszym razem, gdy sprawdzę, że to prawda, i przygotuję listę do zrobienia rzeczy. ale następnym razem w tym indeksie mój indeks nadal będzie index = 0istniał, a teraz ponownie inicjuję ten element na liście, gdy miałem coś robić. Pierwsza myśl dotyczy &&drugiego warunku, takiego jak list.get(index) == nullale to nie działa, dlatego pojawiają się pytania takie jak to
roberto tomás

69

Chociaż otrzymałeś kilkanaście sugestii dotyczących wykorzystania rozmiaru listy, które działają w przypadku list z wpisami liniowymi, nikt nie czytał Twojego pytania.

Jeśli dodasz wpisy ręcznie w różnych indeksach, żadna z tych sugestii nie zadziała, ponieważ musisz sprawdzić określony indeks.

Używanie if (list.get (index) == null) również nie zadziała, ponieważ get () zgłasza wyjątek zamiast zwracać wartość null.

Spróbuj tego:

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

Tutaj dodawany jest nowy wpis, jeśli indeks nie istnieje. Możesz to zmienić, aby zrobić coś innego.


2
Dziękuję, potrzebowałem tej techniki do testowania jednostkowego, czy istnieją indeksy tablic.
Noumenon,

11
Pamiętaj, aby unikać używania try/catchdo tego rodzaju pracy, spowolni to twój program o 50% lub może więcej .. sprawdzanie błędów dodaje jak pasek do istniejącego kodu, aby go spowolnić .. lepiej unikać go w krytycznych obszarach. Sprawdzanie lengthw tym przypadku jest najlepszą rzeczą, jaką możesz zrobić, ponieważ indexzawsze będzie mniej niż lengthstare index, zostaną przesunięte i staną się nowe index, jeśli removeje masz , dlatego sprawdzanie reguły lengthzawsze będzie działać.
SSpoke

1
@SSpoke ... Chociaż zgadzam się, try / catch jest daleki od „dobrej” odpowiedzi; rozwiąże problem, gdy lista jest rzadka. Wolę sugestię użycia tablicy: Object [] ary; poniżej lub hash.
będzie

12

To jest to, czego potrzebujesz ...

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

Dlaczego nie użyć zwykłej starej tablicy? Zindeksowany dostęp do listy to chyba zapach kodu.


3
Nie zawsze, ponieważ może chcieć, aby ArrayList rosła w czasie, a tablica nie może tego zrobić.
Coyote 21

7

Zwykle po prostu sprawdzam, czy indeks jest mniejszy niż rozmiar tablicy

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

Jeśli obawiasz się, że indeks jest wartością ujemną, użyj następujących

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

1
W jaki sposób zapewnia to jakąkolwiek wartość w porównaniu z odpowiedzią przyjętą kilka lat temu?
Basil Bourque

2
Wydaje mi się, że Twoim zdaniem nie daje to żadnej wartości, ale widziałem komentarz Roberta tomása na temat zaakceptowanej odpowiedzi, zakładając, że nie do końca zrozumiał zaakceptowaną odpowiedź. sprawdź to "z nową listą zacznę od index = 0 i moja lista.size () == 0 też. Więc kiedy pierwszy raz sprawdzę, że to prawda" Postanowiłem zamieścić osobną odpowiedź, aby pomóc wszelkie przyszłe zamieszanie.
AamirR

6

Odnośnie twojej aktualizacji (co prawdopodobnie powinno być innym pytaniem). Powinieneś użyć tablicy tych obiektów zamiast ArrayList, więc możesz po prostu sprawdzić wartość null:

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

Najlepsze praktyki

Jeśli nie masz setek wpisów w swojej tablicy, powinieneś rozważyć zorganizowanie jej jako klasy, aby pozbyć się magicznych liczb 3,8 itp.

Sterowanie przepływem za pomocą wyjątku to zła praktyka.


1
Jeśli tablica [8] nie istnieje, napotkasz wyjątek ArrayIndexOutOfBoundException.
Nitesh Kumar Anand


3

Możesz sprawdzić rozmiar za ArrayListpomocą size()metody. Zwróci to maksymalny indeks +1


2

prosty sposób na zrobienie tego:

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

1

Szybki i brudny test, czy indeks istnieje, czy nie. na liście zastąpień implementacji Lista, którą testujesz.

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

lub dla 2Dimensional ArrayLists ...

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

1
Lista nie ma .lengthtego, list.size()ale to nic wielkiego, cały czas tak schrzaniłem haha, polegam na kompilatorze, który poprowadzi mnie po tym. Prawdopodobnie
myślałeś

1
Dzięki, że to złapałeś. Można łatwo zapomnieć o liczności kontenerów.
t3dodson

0

Jeśli twój indeks jest mniejszy niż rozmiar twojej listy, to istnieje, prawdopodobnie z nullwartością. Jeśli indeks jest większy, możesz zadzwonić, ensureCapacity() aby móc użyć tego indeksu.

Jeśli chcesz sprawdzić, czy wartość w Twoim indeksie jest, nullczy nie, zadzwońget()


1
Wywołanie secureCapacity (int) nie zwiększy rozmiaru listy, tylko jej pojemność; tzn. „potencjalny rozmiar”, więc wyszukiwanie w indeksie poza zakresem nadal nie powiedzie się.
Adamski

Poza tym po co w ogóle wywoływać secureCapacity (int)? Może to być niewiarygodnie kosztowna operacja, jeśli na przykład aktualny rozmiar listy to 5 i chcesz określić wartość przedmiotu o numerze: 100 000 000.
Adamski

Miałem na myśli, że indeksy mniejsze niż size () zawsze istnieją, te które są> = size () nie i nie można ich używać (== call set ()) dopóki lista nie stanie się wystarczająco duża. Wywołanie secureCapacity nie wystarczy, trzeba zmienić rozmiar poprzez dodanie elementów.
Dmitry

Nieprawidłowe wyjaśnienie, czym właściwie jest funkcja secureCapacity (int). Nie robi nic z rozmiarem ArrayList.
Mohsen,

0

Możesz sprawdzić rozmiar tablicy.

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'
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.