java: ArrayList - comment puis-je vérifier si un index existe?

111

J'utilise ArrayList<String>et j'ajoute des données à des index spécifiques, comment puis-je vérifier si un index spécifique existe?

Dois-je simplement get()et vérifier la valeur? Ou devrais-je attendre une exception? Y a-t-il un autre moyen?

Mettre à jour

Merci pour vos réponses, mais comme je n'ajoute que des éléments à des index spécifiques, la longueur de la liste ne me montrera pas lesquels sont disponibles.

ufk
la source
2
Jetez un œil à un ensemble peut-être plus adapté à ce dont vous avez besoin?
Paul Whelan
3
Ensuite, vous devrez get()vérifier null- ne vous fiez pas aux exceptions. Pensez à utiliser à la HashTableplace un java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html
Amarghosh
impressionnant!! Je vais utiliser HashTable merci
ufk

Réponses:

159

La méthode arrayList.size() renvoie le nombre d'éléments dans la liste - donc si l'index est supérieur ou égal à size(), il n'existe pas.

if(index >= myList.size()){
  //index not exists
}else{
 // index exists
}
Amarghosh
la source
10
Cela devrait être "supérieur ou égal à size()" puisqu'il s'agit d'un index de base zéro.
McDowell
1
Il convient également de mentionner que pour rendre cet atomique, vous devriez probablement effectuer la vérification de size () et la recherche basée sur l'index conditionnel correspondant tout en verrouillant la liste.
Adamski
3
Veuillez noter que je marque cette réponse à la bonne est parce que le propriétaire (Amarghosh) a répondu à ma question dans un commentaire à ma question. HashTable répondra beaucoup mieux à mes besoins.
ufk du
Que faire si vous définissez des éléments dans la liste arraylist avec l'ID de l'élément? ex. mylist.set (1, élément1); mylist.set (3, élément3); // sauter 2 Je suppose que HashMap est plus approprié pour ce scénario?
yeahman
cela ne me satisfait pas tout à fait .. si je veux faire quelque chose dans la liste si l'index est déjà là, mais sinon pour le préparer .. avec une nouvelle liste je vais commencer index = 0et la mienne list.size() == 0aussi. donc la première fois que je vérifierai ce sera vrai et je préparerai la liste pour faire des choses. mais la prochaine fois à cet index, mon index sera toujours index = 0et maintenant je réinitialise cet élément dans la liste alors que j'étais censé faire des choses. La première pensée est à &&une deuxième condition, list.get(index) == nullmais cela ne fonctionne pas, c'est pourquoi il y a des questions comme celle-ci
roberto tomás
69

Bien que vous ayez reçu une douzaine de suggestions sur l'utilisation de la taille de votre liste, qui fonctionnent pour les listes avec des entrées linéaires, personne n'a semblé lire votre question.

Si vous ajoutez manuellement des entrées à différents index, aucune de ces suggestions ne fonctionnera, car vous devez rechercher un index spécifique.

L'utilisation de if (list.get (index) == null) ne fonctionnera pas non plus, car get () lève une exception au lieu de renvoyer null.

Essaye ça:

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

Ici, une nouvelle entrée est ajoutée si l'index n'existe pas. Vous pouvez le modifier pour faire quelque chose de différent.

pli
la source
2
Merci, j'avais besoin de cette technique pour tester l'unité si les index de tableau existent.
Noumenon
11
N'oubliez pas d'éviter d'utiliser try/catchpour ce genre de travail, cela ralentira votre programme de 50% ou peut-être plus. La vérification des erreurs ajoute comme une sangle à votre code existant pour le ralentir .. mieux vaut l'éviter dans les zones critiques. Vérifier lengthdans ce cas est la meilleure chose que vous puissiez faire, puisque le indexsera toujours moins que le length, les anciens indexseront décalés et deviendront nouveaux indexsi vous removeeux, c'est pourquoi la vérification des règles fonctionnera lengthtoujours.
SSpoke
1
@SSpoke ... Même si je suis d'accord, try / catch est loin d'être une «bonne» réponse; il résoudra le problème lorsque la liste est clairsemée. Je préfère la suggestion d'utiliser un tableau: Object [] ary; ci-dessous ou un hachage.
sera
12

C'est ce dont vous avez besoin ...

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

Pourquoi ne pas utiliser un ancien tableau? L'accès indexé à une liste est une odeur de code, je pense.

Paul McKenzie
la source
3
Pas toujours, car il peut souhaiter que la ArrayList augmente avec le temps, ce qu'un tableau ne peut pas faire.
Coyote21
7

Habituellement, je vérifie simplement si l'index est inférieur à la taille du tableau

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

Si vous craignez également que l'indice soit une valeur négative, utilisez ce qui suit

if (index >= 0 && index < list.size()) {
    ...
}
AamirR
la source
1
Comment cela apporte-t-il une valeur par rapport à la réponse acceptée d'il y a plusieurs années?
Basil Bourque
2
Je suppose qu'à votre avis, cela n'a aucune valeur, mais j'ai vu un commentaire de Roberto Tomás sur la réponse acceptée, en supposant qu'il n'ait pas tout à fait compris la réponse acceptée. check it out "avec une nouvelle liste, je vais commencer à index = 0 et ma list.size () == 0 aussi. Donc la première fois que je vérifie, ce sera vrai" J'ai décidé de publier une réponse séparée pour aider toute confusion future.
AamirR
6

Concernant votre mise à jour (qui devrait probablement être une autre question). Vous devez utiliser un tableau de ces objets à la place d'une ArrayList, vous pouvez donc simplement vérifier la valeur de null:

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

Meilleur entrainement

Si vous n'avez pas des centaines d'entrées dans votre tableau, vous devriez envisager de l'organiser en classe pour vous débarrasser des nombres magiques 3,8 etc.

Contrôler le flux à l'aide d'une exception est une mauvaise pratique

empileur
la source
1
Si le tableau [8] n'existe pas, vous rencontrerez ArrayIndexOutOfBoundException.
Nitesh Kumar Anand
4

Puisqu'il java-9existe un moyen standard de vérifier si un index appartient au tableau - 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
Anton Balaniuc
la source
of()La méthode est également ajoutée dans Java 9 à la liste de classe : docs.oracle.com/javase/9/docs/api/java/util/List.html#of--
Orici
3

Vous pouvez vérifier la taille d'un en ArrayListutilisant la size()méthode. Cela renverra l'indice maximum +1

jwoolard
la source
2

un moyen simple de le faire:

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

Test rapide et sale pour savoir si un index existe ou non. dans votre implémentation, remplacez la liste Avec votre liste que vous testez.

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

ou pour les listes de tableaux 2Dimensional ...

public boolean hasRow(int row){
    if(row < _matrix.size())
        return true;
    return false;
}
t3dodson
la source
1
Liste ne pas .lengthqu'il a , list.size()mais il est pas grand - chose que je visse comme ça tout le temps haha je compte sur le compilateur pour me guider sur celui - là. Vous
pensiez
1
Merci d'avoir attrapé ça. La cardinalité des conteneurs peut être facile à oublier.
t3dodson
0

Si votre index est inférieur à la taille de votre liste, il existe, éventuellement avec une nullvaleur. Si l'index est plus grand, vous pouvez appeler ensureCapacity() pour pouvoir utiliser cet index.

Si vous souhaitez vérifier si une valeur de votre index est nullou non, appelezget()

Dmitry
la source
1
L'appel de ensureCapacity (int) n'augmentera pas la taille de la liste, seulement la capacité; c'est-à-dire "taille potentielle" donc les recherches d'index hors limites échoueraient toujours.
Adamski
Aussi, pourquoi appeler assurerCapacity (int) du tout? Cela peut être une opération extrêmement coûteuse si, par exemple, la taille actuelle de la liste est de 5 et que vous souhaitez déterminer la valeur de l'élément #: 100 000 000.
Adamski
Je voulais dire que les indices inférieurs à size () existent toujours, ceux qui sont> = size () ne le font pas et on ne peut pas les utiliser (== appeler set ()) jusqu'à ce que la liste devienne suffisamment grande. L'appel de ensureCapacity ne suffit pas en effet, il faut changer la taille en ajoutant des éléments.
Dmitry
Mauvaise explication sur ce que fait réellement ensureCapacity (int). Il ne fait rien avec la taille ArrayList.
Mohsen
0

Vous pouvez vérifier la taille du tableau.

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'
    }
}
Miku
la source