修復 Java 中的 NoSuchElementException 錯誤

Mohammad Irfan 2023年10月12日
  1. 在 Java 中使用迭代器時出現 NoSuchElementException
  2. 在 Java 中使用列舉時出現 NoSuchElementException
  3. 在 Java 中使用 StringTokenizer 時出現 NoSuchElementException
  4. 在 Java 中使用 Scanner 類時出現 NoSuchElementException
修復 Java 中的 NoSuchElementException 錯誤

異常是在程式執行期間發生的事件。發生異常時會影響正常的程式流程,導致程式異常終止。本教程將討論 java.util.NoSuchElementException 以及如何在 Java 中處理它。

NoSuchElementException 繼承自 RuntimeException 類,這意味著它是一個未經檢查的異常。編譯器不處理未經檢查的異常,因為它們發生在執行時。

NoSuchElementExceptionScanner 類、Iterator 介面、Enumerator 介面和 StringTokenizer 類丟擲。這些類具有訪問器的方法來從可迭代物件中獲取下一個元素。如果可迭代物件為空或已達到最大限制,它們會丟擲 NoSuchElementException

讓我們看看不同的類如何丟擲 NoSuchElementException

在 Java 中使用迭代器時出現 NoSuchElementException

Iterator 介面有一個名為 next() 的方法,用於訪問迭代中的下一個元素。如果集合中沒有元素,則丟擲 NoSuchElementException。我們將看一些例子。

嘗試迭代沒有元素的 HashMap

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();
  }
}

輸出:

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)

next() 方法丟擲異常,因為 HashMap 為空。我們可以使用 hasNext() 方法來避免這個異常;如果可迭代物件有更多元素,則返回 true。

只有當 hasNext() 返回 True 時,我們才應該使用 next() 方法,以避免此類異常。請參見下面的示例。

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();
    }
  }
}

此程式碼不會引發異常。讓我們以 HashMap 中的一些元素為例並迭代這些元素。

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());
    }
  }
}

輸出:

one
two

如果沒有 hasNext() 方法,這段程式碼會丟擲異常,但它工作正常。

在 Java 中使用列舉時出現 NoSuchElementException

在 Java 中,Enumeration 有一個名為 nextElement() 的方法,它返回列舉的下一個元素。如果沒有要返回的元素,它會丟擲一個 NoSuchElementException

請看下面的示例,我們從列表中建立列舉。

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
  }
}

輸出:

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)

hasElement() 在返回第一個元素後丟擲異常,因為 ArrayList 中沒有任何元素可供訪問。我們可以使用 hasMoreElements() 方法來避免這種情況。

如果列舉中有更多元素要提供,則此方法返回 true;否則,它返回 false。只有當列舉中有更多元素時,我們才能呼叫 nextElement() 方法。

看下面的例子:

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"
    }
  }
}

輸出:

elephant

在 Java 中使用 StringTokenizer 時出現 NoSuchElementException

在 Java 中,StringTokenizer 類提供了兩個方法,nextToken()nextElement()nextToken() 方法從字串標記器返回下一個標記(字串型別),而 nextElement 方法與 nexttoken() 類似,只是它返回的是物件型別而不是字串。這兩種方法都會丟擲 NoSuchElementException

請參見下面的示例。

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
  }
}

輸出:

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)

我們可以使用 hasMoreTokens()hasMoreElements() 方法來避免異常。如果標記器的字串中有更多標記可用,則這兩種方法都返回 true。只有當 hasMoreTokens() 方法返回 True 時,我們才應該呼叫 nextToken() 方法。

請參見下面的示例:

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());
    }
  }
}

輸出:

I
Love
Delft

在 Java 中使用 Scanner 類時出現 NoSuchElementException

Java 中的 Scanner 類提供了幾個實用方法,例如 next()、nextInt() 等。在使用這些方法時,它們可能會丟擲 NoSuchElementException。我們將在這裡討論它們。

  1. 假設你有兩個 Scanner 物件訪問標準輸入。如果你關閉其中一個並使用另一個呼叫方法,則會引發 NoSuchElementException。請參見下面的示例。
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();
  }
}

輸出:

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)

當我們關閉第一個 Scanner 時,它會關閉底層的 InputStream;因此,第二個 Scanner 無法從同一個 InputStream 中讀取資料並丟擲 NoSuchElementException。解決方案是使用一個 Scanner 物件來讀取 System.in 輸入。

  1. 假設你正在使用 Scanner 物件讀取字串或檔案。如果沒有可讀取的行,則會顯示異常。請參見下面的示例。
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());
  }
}

輸出:

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)

為了解決這個問題,我們使用返回布林值的 hasNextLine() 方法。看例子。

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());
    }
  }
}

輸出:

I Love Delft

相關文章 - Java Error