IlleagalStateException Vs NoSuchElementException in java?


When you call a method at illegal or inappropriate time an IlleagalStateException is generated.

For example, the remove() method of the ArrayList class removes the last element after calling the next() or previous methods.

  • After removing the element at the current position you need to move to the next element to remove it i.e. per one call of the next() method you can invoke this remove() method only once.
  • Since the initial position of the list (pointer) will be before the first element, you cannot invoke this method without calling the next method.

If you invoke the remove() method otherwise it throws an java.lang.IllegalStateException.

Example: removing an element before moving to 1st element

import java.util.ArrayList;
import java.util.ListIterator;
public class NextElementExample{
   public static void main(String args[]) {
      //Instantiating an ArrayList object
      ArrayList<String> list = new ArrayList<String>();
      //populating the ArrayList
      list.add("apples");
      list.add("mangoes");
      //Getting the Iterator object of the ArrayList
      ListIterator<String> it = list.listIterator();
      //Removing the element without moving to first position
      it.remove();
   }
}

Runtime exception

Exception in thread "main" java.lang.IllegalStateException
at java.util.ArrayList$Itr.remove(Unknown Source)
at MyPackage.NextElementExample.main(NextElementExample.java:17)

Example: Calling next() method twice after invoking the next() method once

import java.util.ArrayList;
import java.util.ListIterator;
public class NextElementExample{
   public static void main(String args[]) {
      //Instantiating an ArrayList object
      ArrayList<String> list = new ArrayList<String>();
      //populating the ArrayList
      list.add("apples");
      list.add("mangoes");
      //Getting the Iterator object of the ArrayList
      ListIterator<String> it = list.listIterator();
      //Removing the element with out moving to first position
      it.next();
      it.remove();
      it.remove();
   }
}

Output

Exception in thread "main" java.lang.IllegalStateException
   at java.util.ArrayList$Itr.remove(Unknown Source)
   at MyPackage.NextElementExample.main(NextElementExample.java:17)

Trying to invoke this method within a loop also comes under this scenario.

it.next();
while(it.hasNext()) {
   it.remove();
}

Solution

In the above scenario to solve the IllegalStateException you need to invoke the remove() method of the properly (only once after calling next())

Example

import java.util.ArrayList;
import java.util.Arrays;
import java.util.ListIterator;
public class NextElementExample{
   public static void main(String args[]) {
      //Instantiating an ArrayList object
      ArrayList<String> list = new ArrayList<String>();
      //populating the ArrayList
      list.add("apples");
      list.add("mangoes");
      //Getting the Iterator object of the ArrayList
      ListIterator<String> it = list.listIterator();
      //Removing the element with out moving to first position
      System.out.println(Arrays.toString(list.toArray()));
      while(it.hasNext()) {
         it.next();
         it.remove();
      }  
      System.out.println(Arrays.toString(list.toArray()));
   }
}

Output

[apples, mangoes]
[]

Similarly, in each scenario to handle Illegal state exception, you need to invoke the method that caused the exception in its legal position.

NosuchElementException

While accessing the contents of a collection, array or other objects using the accessor methods of an Enumeration, Iterator or, tokenizer, such as next() or nextElement(), if you try to get the elements from an empty object, or if you try to get the next element after reaching the end of the object (collection, array, or other) a NoSuchElementException is generated.

For example,

  • If you call the nextElement() method of the Enumeration class on an empty enumeration object or, if the current position is at the end of the Enumeration, a NosuchElementException is generated at run time.
  • If you invoke the nextElement() and nextToken() methods of the StringTokenizer class on an empty StringTokenizer object or, if the current position is at the end of the StringTokenizer, a NosuchElementException is generated at run time.
  • If the next() methods of the Iterator or ListIterator classes, invoked on an empty Iterator/ListIterator or, if the current position is at the end, the Iterator/listIterator NosuchElementException is generated at run time.
  • Similarly if the previous() method of the ListIterator class is invoked on an empty ListIterator object, or if the current position is the start of the ListIterator a NosuchElementException is generated at run time.

Example

Let us consider complete example of one scenario

import java.util.StringTokenizer;
public class StringTokenizerExample{
   public static void main(String args[]) {
      String str = "Hello how are you";
      //Instantiating the StringTokenizer class
      StringTokenizer tokenizer = new StringTokenizer(str, " ");
      //Printing all the tokens
      System.out.println(tokenizer.nextToken());
      System.out.println(tokenizer.nextToken());
      System.out.println(tokenizer.nextToken());
      System.out.println(tokenizer.nextToken());
      //Getting the next token after reaching the end
      tokenizer.nextToken();
      tokenizer.nextElement();
   }
}

Runtime error

Hello
how
are
you
Exception in thread "main" java.util.NoSuchElementException
   at java.util.StringTokenizer.nextToken(Unknown Source)
   at MyPackage.StringTokenizerExample.main(StringTokenizerExample.java:16)

Solution

Almost all the classes whose accessor method causes NoSuchElementException contains their respective methods to verify whether the object (collection, tokenizer etc.) contains more elements.

For example,

  • The Enumeration class contains a method named hasMoreElements() which returns true if the current object contains more elements after the current position (else it returns false).
  • The StringTokenizer class contains methods named hasMoreTokens() and hasMoreElements() which returns true if the current object contains more elements after the current position (else it returns false).
  • The Iterator class contains hasNext() method this also returns true if the current iterator contains more elements next to the current position (else it returns false).
  • The ListIterator class contains hasPrevious() method this also returns true if the current iterator contains more elements previously to the current position (else it returns false).

Example

import java.util.StringTokenizer;
public class StringTokenizerExample{
   public static void main(String args[]) {
      String str = "Hello how are you";
      //Instantiating the StringTokenizer class
      StringTokenizer tokenizer = new StringTokenizer(str, " ");
      //Printing all the tokens
      while(tokenizer.hasMoreTokens()) {
         System.out.println(tokenizer.nextToken());
      }
   }
}

Output

Hello
how
are
you

Difference

The main difference between these two exceptions is that the IllegalStateException is generated when you invoke a method in illegal position in the program

Whereas the NoElementException is generated if you try to access the elements of an Enumeration, Iterator, StringTokenizer etc. (using accessor methods) when there are no more elements in them.

Updated on: 19-Sep-2019

141 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements