为什么我一直得到NoSuchElementException?

时间:2013-11-20 05:34:42

标签: java file exception

这是我目前的代码。由于某种原因,我不断得到并且调用了错误:NoSuchElementException:找不到行。例外情况发生在以下行:
"String number = scanPhone.nextLine();"
和提供者类以及行中:"provObj.readCellPhoneFile(fileNameIn);"
在CellPhonesPart2类中。有谁知道它有什么问题?

import java.util.Scanner;
import java.io.File;
import java.util.Arrays;
import java.io.IOException;

public class Provider {
   private String name;
   private CellPhone[] phones;
   private String[] excludedRecords;

   /**
    * Constructor for Provider class.
    */
   public Provider() {
      name = "not yet assigned";
      phones = new CellPhone[0];
      excludedRecords = new String[0];
   }

   /**
    * Reads in file name and assigns data.
    *
    * @param fileNameIn Input for file name from main
    * @throws IOException from scanning file name
    */
   public void readCellPhoneFile(String fileNameIn) throws IOException {
      //Reads in file name and creates Scanner object
      File fileIn = new File(fileNameIn);
      Scanner scanFile = new Scanner(fileIn);
      //Assigns name from first line
      name = scanFile.nextLine();
      //Assigns data from file to different categories
      while (scanFile.hasNext()) {
         Scanner scanPhone = new Scanner(scanFile.nextLine());
         scanPhone.useDelimiter(", *");

         String phoneType = scanPhone.nextLine();
         char phoneChar = phoneType.toUpperCase().charAt(0);

         //Assigns phone to different category
         switch (phoneChar) {   
            case 'F':
               String number = scanPhone.nextLine();
               int texts = Integer.parseInt(scanPhone.nextLine());
               int minutes = Integer.parseInt(scanPhone.nextLine());
               FlipPhone flip1 = new FlipPhone(number, texts, minutes);
               addPhone(flip1);
               break;
            case 'S':
               number = scanPhone.nextLine();
               texts = Integer.parseInt(scanPhone.nextLine());
               minutes = Integer.parseInt(scanPhone.nextLine());
               int data = Integer.parseInt(scanPhone.nextLine());
               SmartPhone smart1 = new SmartPhone(number, texts, minutes, data);
               addPhone(smart1);
               break;
            case 'I':
               number = scanPhone.nextLine();
               texts = Integer.parseInt(scanPhone.nextLine());
               minutes = Integer.parseInt(scanPhone.nextLine());
               data = Integer.parseInt(scanPhone.nextLine());
               int iMessages = Integer.parseInt(scanPhone.nextLine());
               IPhone iPhone1 = new IPhone(number, texts,
                  minutes, data, iMessages);
               addPhone(iPhone1);
               break;
            case 'A':
               number = scanPhone.nextLine();
               texts = Integer.parseInt(scanPhone.nextLine());
               minutes = Integer.parseInt(scanPhone.nextLine());
               data = Integer.parseInt(scanPhone.nextLine());
               int hotspotMin = Integer.parseInt(scanPhone.nextLine());
               Android android1 = new Android(number, texts,
                  minutes, data, hotspotMin);
               addPhone(android1);
               break;
            default:
               String unrecognized = scanPhone.nextLine();
               addExcludedRecord(unrecognized);   
         }
      }   
   }

   /**
    * Returns string for provider name.
    *
    * @return String
    */
   public String getName() {
      return name;
   }

   /**
    * Assigns a name input as provider name.
    *
    * @param nameIn Input for provider name
    */
   public void setName(String nameIn) {
      name = nameIn;
   }

   /**
    * Returns CellPhone array for phones.
    *
    * @return CellPhone[]
    */
   public CellPhone[] getPhones() {
      return phones;
   }

   /**
    * Returns string array for excluded records.
    *
    * @return String[]
    */
   public String[] getExcludedRecords() {
      return excludedRecords;
   }

   /**
    * Adds phone to array of phones.
    *
    * @param newPhoneIn Input for phone object
    */
   public void addPhone(CellPhone newPhoneIn) {
      //Increases size of phones array
      CellPhone[] newPhones = new CellPhone[phones.length + 1];
      for (int i = 0; i < phones.length; i++) {
         newPhones[i] = phones[i];
      }
      phones = newPhones;
      //Adds CellPhone object to phones array
      phones[phones.length] = newPhoneIn;
   }

   /**
    * Determines if phone number is found and deleted.
    *
    * @return boolean
    * @param numberIn Input for phone number
    */
   public boolean deletePhone(String numberIn) {
      boolean delete = false;
      int deleteIndex = -1;
      //Searches for phone number match
      for (int i = 0; i < phones.length; i++) {
         if (numberIn == phones[i].getNumber()) {
            deleteIndex = i;
            //Decreases size of phones array
            CellPhone[] newPhones = new CellPhone[phones.length - 1];
            for (i = 0; i < phones.length; i++) {
               newPhones[i] = phones[i];
            }
            phones = newPhones;
         }
      }   
      if (deleteIndex > -1) {
         for (int i = deleteIndex; i < phones.length - 1; i++) {
            phones[i] = phones[i + 1];
         }
         return true;
      }
      else {
         return false;
      }
   }

   /**
    * Adds unrecognized phone to excluded records.
    *
    * @param excRecIn Input for unrecognized phone
    */
   public void addExcludedRecord(String excRecIn) {
      //Increases capacity of excludedRecords
      String[] newExcRecords = new String[excludedRecords.length + 1];
      for (int i = 0; i < excludedRecords.length; i++) {
         newExcRecords[i] = excludedRecords[i];
      }
      excludedRecords = newExcRecords;
      //Adds excRecIn to array
      excludedRecords[excludedRecords.length] = excRecIn;
   }

   /**
    * Returns list of cell phones in phones array.
    *
    * @return String
    */
   public String toString() {
      String result = "";
      for (CellPhone phone : phones) {
         result += phone;
      }
      return result;
   }

   /**
    * Calculates total bill for all phones.
    *
    * @return double
    */
   public double calculateTotalBill() {
      double totalBill = 0;
      for (int i = 0; i < phones.length; i++) {
         totalBill += phones[i].calculateBill();
      }   
      return totalBill;
   }

   /**
    * Calculates total number of texts for all phones.
    *
    * @return int
    */
   public int calculateTotalTexts() {
      int totalTexts = 0;
      for (int i = 0; i < phones.length; i++) {
         totalTexts += phones[i].getTexts();
      }   
      return totalTexts;
   }

   /**
    * Calculates total number of minutes for all phones.
    *
    * @return int
    */
   public int calculateTotalMinutes() {
      int totalMinutes = 0;
      for (int i = 0; i < phones.length; i++) {
         totalMinutes += phones[i].getMinutes();
      }   
      return totalMinutes;
   }

   /**
    * Calculates total data for smartphones.
    *
    * @return int
    */
   public int calculateTotalData() {
      int totalData = 0;
      for (int i = 0; i < phones.length; i++) {
         if (phones[i] instanceof SmartPhone) {
            totalData += ((SmartPhone) phones[i]).getData();
         }   
      }   
      return totalData;
   }

   /**
    * Calculates total hotspot minutes for Androids.
    *
    * @return int
    */
   public int calculateTotalHotspotMin() {
      int totalHotspotMin = 0;
      for (int i = 0; i < phones.length; i++) {
         if (phones[i] instanceof Android) {
            totalHotspotMin += ((Android) phones[i]).getHotspotMin();
         }   
      }   
      return totalHotspotMin;
   }

   /**
    * Calculates total iMessage count for iPhones.
    *
    * @return int
    */
   public int calculateTotalIMessages() {
      int totalIMessages = 0;
      for (int i = 0; i < phones.length; i++) {
         if (phones[i] instanceof IPhone) {
            totalIMessages += ((IPhone) phones[i]).getIMessages();
         }   
      }   
      return totalIMessages;
   }

   /**
    * Returns string for summary report.
    *
    * @return String
    */
   public String summary() {
      String summary = "------------------------------"
         + "\nSummary for " + getName()
         + "\n------------------------------"
         + "\nNumber of cell phones: " + getPhones()
         + "Texts: " + calculateTotalTexts()
         + "Talk Minutes: " + calculateTotalMinutes()
         + "Data: " + calculateTotalData()
         + "Hotspot Minutes: " + calculateTotalHotspotMin()
         + "iMessages: " + calculateTotalIMessages()
         + "Bill Total: $" + calculateTotalBill()
         + "\n\n------------------------------"
         + "\nRates for " + getName()
         + "\n------------------------------"
         + rates()
         + "\n------------------------------"
         + "\nCell Phones by Number"
         + "\n------------------------------\n"
         + listByNumber()
         + "\n------------------------------"
         + "\nCell Phones by Billing Amount"
         + "\n------------------------------\n"
         + listByBill()
         + "\n------------------------------"
         + "\nExcluded Records"
         + "\n------------------------------\n"
         + excludedRecordsList();
      return summary;
   }

   /**
    * Returns string for different rates.
    *
    * @return String
    */
   public String rates() {
      String rates = "FlipPhone Talk Rate: $" + FlipPhone.TALK_RATE
         + "\tText Rate: $" + FlipPhone.TEXT_RATE
         + "SmartPhone Talk Rate: $" + SmartPhone.TALK_RATE
         + "\tText Rate: $" + SmartPhone.TEXT_RATE
         + "\tMax Talk Time: " + SmartPhone.MAX_TALK_TIME
         + "\n\tiPhone iMessage Rate: $" + IPhone.IMESSAGE_RATE
         + "\n\tAndroid HotspotRate: $" + Android.HOTSPOT_RATE;
      return rates;
   }

   /**
    * Returns string of phones sorted by number.
    *
    * @return String
    */
   public String listByNumber() {
      String listByNumber = "";
      for (CellPhone phone : phones) {
         listByNumber += phone.toString();
      }
      Arrays.sort(phones);
      return listByNumber;
   }

   /**
    * Returns string of phones sorted by bill.
    *
    * @return String
    */
   public String listByBill() {
      String listByBill = "";
      for (CellPhone phone : phones) {
         listByBill += phone.toString();
      }
      Arrays.sort(phones, new CellPhoneBillComparator());
      return listByBill;
   }

   /**
    * Returns string excluded records.
    *
    * @return String
    */
   public String excludedRecordsList() {
      String excRecList = "";
      for (String phone : excludedRecords) {
         excRecList += phone;
      }
      return excRecList;
   }
}

它从这个类中读取文件:

public class CellPhonesPart2 {

   /** 
    * Creates objects from different classes and prints objects. 
    *
    * @param args Reads in file
    * @throws IOException from scanning input file
    */
   public static void main(String[] args) throws IOException {
      String fileNameIn = args[0];
      Provider provObj = new Provider();
      provObj.readCellPhoneFile(fileNameIn);

      System.out.println(provObj.summary());
   }
}

2 个答案:

答案 0 :(得分:0)

你应该在调用nextLine()之前使用适当的hasNext(); 扫描仪可能是空的。!

答案 1 :(得分:0)

Scanner scanPhone = new Scanner(scanFile.nextLine());
// this is causing your error. scanPhone is ultimately just a one line String

// this line will be found
String phoneType = scanPhone.nextLine();

// this line won't because scanPhone is only one line
String number = scanPhone.nextLine();

编辑:可能的解决方案

 while (scanFile.hasNextLine()) {
     Scanner scanPhone = new Scanner(scanFile.nextLine());
     scanPhone.useDelimiter(", *");

     String phoneType = scanPhone.next();
     char phoneChar = phoneType.toUpperCase().charAt(0);

     //Assigns phone to different category
     switch (phoneChar) {   
        case 'F':
           String number = scanPhone.next();
           int texts = Integer.parseInt(scanePhone.next());
           int minutes = Integer.parseInt(scanPhone.next());
           FlipPhone flip1 = new FlipPhone(number, texts, minutes);
           addPhone(flip1);
           break;

将所有scanPhone.nextLine()更改为scanPhone.next()

另外,请尝试使用while (scanFile.hasNextLine());代替hasNext()