Correction de l'erreur NoSuchElementException en Java

Mohammad Irfan 12 octobre 2023
  1. NoSuchElementException lors de l’utilisation d’Iterator en Java
  2. NoSuchElementException lors de l’utilisation de l’énumération en Java
  3. NoSuchElementException lors de l’utilisation de StringTokenizer en Java
  4. NoSuchElementException lors de l’utilisation de la classe Scanner en Java
Correction de l'erreur NoSuchElementException en Java

Une exception est un événement qui se produit pendant l’exécution d’un programme. Le déroulement normal du programme est affecté lorsqu’une exception se produit et le programme se termine anormalement. Ce tutoriel discutera de java.util.NoSuchElementException et comment le gérer en Java.

L’NoSuchElementException hérite de la classe RuntimeException, ce qui signifie qu’il s’agit d’une exception non cochée. Les exceptions non cochées ne sont pas gérées par le compilateur, car elles se produisent pendant l’exécution.

L’exception NoSuchElementException est levée par la classe Scanner, l’interface Iterator, l’interface Enumerator et la classe StringTokenizer. Ces classes ont des méthodes d’accès pour récupérer l’élément suivant d’un itérable. Ils lancent NoSuchElementException si l’itérable est vide ou a atteint la limite maximale.

Regardons comment différentes classes lancent NoSuchElementException.

NoSuchElementException lors de l’utilisation d’Iterator en Java

L’interface Iterator possède une méthode appelée next() utilisée pour accéder à l’élément suivant dans l’itération. Si aucun élément n’est dans la collection, alors NoSuchElementException est levée. Nous allons regarder quelques exemples.

Essayer d’itérer un HashMap sans éléments :

import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    // creating a hashmap with no element
    HashMap<String, Integer> h1 = new HashMap<>();
    // creating an iterator object
    Iterator i = h1.keySet().iterator();
    // trying to access element
    i.next();
  }
}

Production :

Exception in thread "main" java.util.NoSuchElementException
    at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1599)
    at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1620)
    at MyClass.main(MyClass.java:9)

La méthode next() lève une exception car le HashMap est vide. Nous pouvons utiliser la méthode hasNext() pour éviter cette exception ; il renvoie true si l’itérable a plus d’éléments.

Nous devrions utiliser la méthode next() uniquement si hasNext() renvoie True, pour éviter de telles exceptions. Voir l’exemple ci-dessous.

import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    // creating a hashmap with no element
    HashMap<String, Integer> h1 = new HashMap<>();
    // creating an iterator object
    Iterator i = h1.keySet().iterator();
    // trying to access element
    while (i.hasNext()) {
      i.next();
    }
  }
}

Ce code ne lève aucune exception. Prenons un exemple avec quelques éléments dans le HashMap et itérons les éléments.

import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    // creating a hashmap
    HashMap<String, Integer> h1 = new HashMap<>();
    h1.put("one", 1);
    h1.put("two", 2);
    // creating an iterator object
    Iterator i = h1.keySet().iterator();
    // trying to access element
    while (i.hasNext()) {
      System.out.println(i.next());
    }
  }
}

Production :

one
two

Sans la méthode hasNext(), ce code aurait généré une exception, mais il fonctionne correctement.

NoSuchElementException lors de l’utilisation de l’énumération en Java

En Java, Enumeration a une méthode appelée nextElement() qui renvoie l’élément suivant de l’énumération. S’il n’y a pas d’élément à retourner, il lève une NoSuchElementException.

Regardez l’exemple ci-dessous où nous créons une énumération à partir d’une liste.

import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    ArrayList<String> animals = new ArrayList<>();
    animals.add(new String("elephant"));
    // creating enumeration object
    Enumeration en = Collections.enumeration(animals);
    System.out.println(en.nextElement()); // gets "elephant"
    System.out.println(en.nextElement()); // throws exception
  }
}

Production :

elephant

Exception in thread "main" java.util.NoSuchElementException
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:970)
    at java.base/java.util.Collections$3.nextElement(Collections.java:5440)
    at MyClass.main(MyClass.java:9)

Le hasElement() lève une exception après avoir renvoyé le premier élément car il ne reste aucun élément dans la ArrayList pour y accéder. Nous pouvons utiliser la méthode hasMoreElements() pour éviter cette situation.

Cette méthode retourne true s’il y a plus d’éléments dans l’énumération à fournir ; sinon, il renvoie faux. Nous ne pouvons appeler la méthode nextElement() que s’il y a plus d’éléments dans l’énumération.

Regardez l’exemple ci-dessous :

import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    ArrayList<String> animals = new ArrayList<>();
    animals.add(new String("elephant"));
    // creating enumeration object
    Enumeration en = Collections.enumeration(animals);
    while (en.hasMoreElements()) {
      System.out.println(en.nextElement()); // gets "elephant"
    }
  }
}

Production :

elephant

NoSuchElementException lors de l’utilisation de StringTokenizer en Java

En Java, la classe StringTokenizer fournit deux méthodes, le nextToken() et le nextElement(). La méthode nextToken() renvoie le jeton suivant (type de chaîne) à partir du générateur de jetons de chaîne, tandis que la méthode nextElement() est comme le nextToken() sauf qu’elle renvoie un type d’objet plutôt qu’une chaîne. Les deux méthodes lancent l’exception NoSuchElementException.

Voir l’exemple ci-dessous.

import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    String s = "I Love Delft";
    StringTokenizer st = new StringTokenizer(s);
    System.out.println(st.nextToken()); // gets I
    System.out.println(st.nextToken()); // gets Love
    System.out.println(st.nextToken()); // gets Delft
    System.out.println(st.nextToken()); // Throws exception
  }
}

Production :

I
Love
Delft

Exception in thread "main" java.util.NoSuchElementException
    at java.base/java.util.StringTokenizer.nextToken(StringTokenizer.java:347)
    at MyClass.main(MyClass.java:9)

Nous pouvons éviter l’exception en utilisant les méthodes hasMoreTokens() et hasMoreElements(). Les deux méthodes renvoient true si plus de jetons sont disponibles dans la chaîne du tokenizer. Nous ne devrions appeler la méthode nextToken() que si la méthode hasMoreTokens() renvoie True.

Voir l’exemple ci-dessous :

import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    String s = "I Love Delft";
    StringTokenizer st = new StringTokenizer(s);
    while (st.hasMoreTokens()) {
      System.out.println(st.nextToken());
    }
  }
}

Production :

I
Love
Delft

NoSuchElementException lors de l’utilisation de la classe Scanner en Java

La classe Scanner en Java fournit plusieurs méthodes utilitaires telles que next(), nextInt(), etc. Tout en travaillant avec ces méthodes, elles peuvent lancer l’exception NoSuchElementException. Nous en discuterons ici.

  1. Supposons que deux objets scanner accèdent à l’entrée standard. Si vous fermez l’un d’eux et appelez une méthode en utilisant l’autre, il lève le NoSuchElementException. Voir l’exemple ci-dessous.
import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    String s = "I Love Delft";
    Scanner s1 = new Scanner(System.in);
    Scanner s2 = new Scanner(System.in);
    s1.close();
    s2.next();
  }
}

Production :

Exception in thread "main" java.util.NoSuchElementException
    at java.base/java.util.Scanner.throwFor(Scanner.java:937)
    at java.base/java.util.Scanner.next(Scanner.java:1478)
    at MyClass.main(MyClass.java:8)

Lorsque nous fermons le premier Scanner, il ferme le InputStream sous-jacent ; par conséquent, le second Scanner ne peut pas lire à partir du même InputStream et lève une NoSuchElementException. La solution consiste à utiliser un objet scanner pour lire l’entrée System.in.

  1. Supposons que vous lisiez une chaîne ou un fichier à l’aide de l’objet scanner. S’il n’y a plus de ligne à lire, une exception s’affiche. Voir l’exemple ci-dessous.
import java.util.*;
public class MyClass {
  public static void main(String args[]) {
    String s = "I Love Delft";
    Scanner s1 = new Scanner(s);
    System.out.println(s1.nextLine());
    System.out.println(s1.nextLine());
  }
}

Production :

I Love Delft

Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
    at MyClass.main(MyClass.java:7)

Pour résoudre ce problème, nous utilisons la méthode hasNextLine() qui renvoie une valeur booléenne. Regardez l’exemple.

import java.util.*;
public class Main {
  public static void main(String args[]) {
    String s = "I Love Delft";
    Scanner s1 = new Scanner(s);
    while (s1.hasNextLine()) {
      System.out.println(s1.nextLine());
    }
  }
}

Production :

I Love Delft

Article connexe - Java Error