java: ArrayList - come posso verificare se esiste un indice?


111

Sto utilizzando ArrayList<String>e aggiungo dati a indici specifici, come posso verificare se esiste un indice specifico?

Devo semplicemente get()e controllare il valore? O devo aspettare un'eccezione? C'è un altro modo?

Aggiornare

Grazie per le tue risposte, ma poiché sto solo aggiungendo elementi a indici specifici, la lunghezza dell'elenco non mi mostrerà quali sono disponibili.


2
Dai un'occhiata a un set forse è più adatto a ciò di cui hai bisogno?
Paul Whelan

3
Allora dovrai farlo get()e controllare null, non fare affidamento sulle eccezioni però. Considera l' HashTable
idea di

eccezionale!!
Userò

Risposte:


159

Il metodo arrayList.size() restituisce il numero di elementi nell'elenco, quindi se l'indice è maggiore o uguale a size(), non esiste.

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

10
Dovrebbe essere "maggiore o uguale a size()" poiché è un indice a base zero.
McDowell

1
Vale anche la pena ricordare che per renderlo atomico dovresti probabilmente eseguire il controllo size () e la corrispondente ricerca basata sull'indice condizionale mentre blocchi l'elenco.
Adamski

3
si prega di notare che contrassegno questa risposta come corretta perché il proprietario (Amarghosh) ha risposto alla mia domanda in un commento alla mia domanda. HashTable soddisferà le mie esigenze molto meglio.
ufk

cosa succede se si stanno impostando elementi nella lista di array con l'ID dell'articolo? ex. mylist.set (1, item1); mylist.set (3, item3); // saltando 2 Immagino che HashMap sia più adatto per quello scenario?
yeahman

questo non mi soddisfa abbastanza .. se voglio fare qualcosa nella lista se l'indice è già lì, ma altrimenti prepararla .. con una nuova lista da cui inizierò index = 0e list.size() == 0anche la mia . quindi la prima volta che controllo sarà vero e preparo l'elenco per fare le cose. ma la prossima volta in quell'indice, il mio indice sarà ancora index = 0e ora sto reinizializzando quell'elemento nell'elenco quando avrei dovuto fare qualcosa. Il primo pensiero è quello di &&una seconda condizione come list.get(index) == nullma non funziona è per questo che ci sono domande come questa
roberto tomás

69

Sebbene tu abbia ricevuto una dozzina di suggerimenti sull'utilizzo della dimensione del tuo elenco, che funziona per elenchi con voci lineari, nessuno sembrava leggere la tua domanda.

Se aggiungi voci manualmente a indici diversi, nessuno di questi suggerimenti funzionerà, poiché devi verificare la presenza di un indice specifico.

Anche l'uso di if (list.get (index) == null) non funzionerà, poiché get () genera un'eccezione invece di restituire null.

Prova questo:

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

Qui viene aggiunta una nuova voce se l'indice non esiste. Puoi modificarlo per fare qualcosa di diverso.


2
Grazie, avevo bisogno di questa tecnica per testare l'unità se esistono indici di array.
Noumenon

11
Ricorda di evitare di utilizzare try/catchper questo tipo di lavoro, rallenterà il tuo programma del 50% o forse di più .. il controllo degli errori aggiunge come una cinghia al tuo codice esistente per rallentarlo .. meglio evitarlo nelle aree critiche. Il controllo lengthin questo caso è la cosa migliore che puoi fare, dal momento che indexsarà sempre meno di length, i vecchi indexverranno spostati e diventeranno nuovi indexse removeli fai , ecco perché il controllo delle regole funzionerà lengthsempre.
S ha parlato il

1
@SSpoke ... Anche se sono d'accordo, try / catch è tutt'altro che "una buona" risposta; risolverà il problema quando l'elenco è scarso. Preferisco il suggerimento di utilizzare un array: Object [] ary; sotto o un hash.
sarà il

12

Questo è quello di cui hai bisogno ...

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

Perché non utilizzare un semplice vecchio array? L'accesso indicizzato a un elenco è un odore di codice credo.


3
Non sempre, dal momento che potrebbe volere che ArrayList cresca nel tempo e che un array non può fare.
Coyote21

7

Di solito controllo solo se l'indice è inferiore alla dimensione dell'array

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

Se sei anche preoccupato che l'indice sia un valore negativo, usa quanto segue

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

1
In che modo ciò fornisce un valore rispetto alla risposta accettata di diversi anni fa?
Basil Bourque

2
Immagino che dal tuo punto di vista non fornisca alcun valore, ma ho visto un commento di roberto tomás sulla risposta accettata, supponendo che non abbia capito bene la risposta accettata. dai un'occhiata "con un nuovo elenco inizierò da index = 0 e anche da list.size () == 0. quindi la prima volta che controllo che sarà vero" ho deciso di pubblicare una risposta separata per aiutare qualsiasi futura confusione.
AamirR

6

Per quanto riguarda il tuo aggiornamento (che probabilmente dovrebbe essere un'altra domanda). Dovresti usare un array di questi oggetti invece di un ArrayList, quindi puoi semplicemente controllare il valore per null:

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

La migliore pratica

Se non hai centinaia di voci nel tuo array dovresti considerare di organizzarlo come una classe per sbarazzarti dei numeri magici 3,8 ecc.

Controllare il flusso utilizzando l'eccezione è una cattiva pratica.


1
Se l'array [8] non esiste, incontrerai ArrayIndexOutOfBoundException.
Nitesh Kumar Anand


3

Puoi controllare la dimensione di un ArrayListutilizzando il size()metodo. Ciò restituirà l'indice massimo +1


2

un modo semplice per farlo:

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

1

Test rapido e sporco per verificare se un indice esiste o meno. nella tua lista di sostituzione dell'implementazione Con la tua lista stai testando.

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

o per elenchi di matrici 2Dimensionali ...

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

1
L'elenco non ce .lengthl'ha, list.size()ma non è un grosso problema, faccio un casino in questo modo tutto il tempo haha ​​mi affido al compilatore per guidarmi su quello. Probabilmente stavi pensando agli array primitivi
S ha parlato il

1
Grazie per averlo capito. La cardinalità dei contenitori può essere facilmente dimenticata.
t3dodson

0

Se il tuo indice è inferiore alla dimensione del tuo elenco, allora esiste, possibilmente con nullvalore. Se index è più grande, puoi chiamare ensureCapacity() per poter utilizzare quell'indice.

Se vuoi controllare se un valore nel tuo indice è nullo meno, chiamaget()


1
La chiamata a sureCapacity (int) non aumenterà la dimensione dell'elenco, ma solo la capacità; vale a dire "dimensione potenziale", quindi le ricerche di indici fuori dai limiti continuerebbero a fallire.
Adamski

Inoltre, perché chiamare assicurareCapacity (int)? Potrebbe essere un'operazione incredibilmente costosa se, ad esempio, la dimensione corrente dell'elenco è 5 e si desidera determinare il valore dell'elemento #: 100.000.000.
Adamski

Intendevo che gli indici inferiori a size () esistono sempre, quelli che sono> = size () no e non si possono usarli (== call set ()) finché la lista non diventa abbastanza grande. Chiamare sureCapacity non è sufficiente, è necessario modificare le dimensioni aggiungendo elementi.
Dmitry

Spiegazione sbagliata su cosa fa in realtà sureCapacity (int). Non fa nulla con la dimensione di ArrayList.
Mohsen

0

È possibile verificare la dimensione dell'array.

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'
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.