2013-11-21 37 views
1

伙计。现在,我有一个从阅读文本文件中分配的对象数组,我需要一个方法来搜索与该对象匹配的字符串,并且如果找到,会减少数组的容量并删除元件。该方法是Provider类中的deletePhone()方法,但我似乎无法弄清楚我做错了什么。这第一个类只用于读取文件。如何从对象数组中删除元素?

public static void main(String[] args) throws IOException { 
     String fileNameIn = args[0]; 
     Provider provObj = new Provider(); 
     provObj.readCellPhoneFile(fileNameIn); 

     System.out.println(provObj.summary()); 
     System.out.println(provObj.rates()); 
     System.out.println(provObj.listByNumber()); 
     System.out.println(provObj.listByBill()); 
     System.out.println(provObj.excludedRecordsList()); 
    } 
} 

这是我遇到问题的主要类。这只是我看不出来的deletePhone()方法。

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

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.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(scanPhone.next()); 
       int minutes = Integer.parseInt(scanPhone.next()); 
       FlipPhone flip1 = new FlipPhone(number, texts, minutes); 
       addPhone(flip1); 
       break; 
      case 'S': 
       number = scanPhone.next(); 
       texts = Integer.parseInt(scanPhone.next()); 
       minutes = Integer.parseInt(scanPhone.next()); 
       int data = Integer.parseInt(scanPhone.next()); 
       SmartPhone smart1 = new SmartPhone(number, texts, minutes, data); 
       addPhone(smart1); 
       break; 
      case 'I': 
       number = scanPhone.next(); 
       texts = Integer.parseInt(scanPhone.next()); 
       minutes = Integer.parseInt(scanPhone.next()); 
       data = Integer.parseInt(scanPhone.next()); 
       int iMessages = Integer.parseInt(scanPhone.next()); 
       IPhone iPhone1 = new IPhone(number, texts, 
        minutes, data, iMessages); 
       addPhone(iPhone1); 
       break; 
      case 'A': 
       number = scanPhone.next(); 
       texts = Integer.parseInt(scanPhone.next()); 
       minutes = Integer.parseInt(scanPhone.next()); 
       data = Integer.parseInt(scanPhone.next()); 
       int hotspotMin = Integer.parseInt(scanPhone.next()); 
       Android android1 = new Android(number, texts, 
        minutes, data, hotspotMin); 
       addPhone(android1); 
       break; 
      default: 
       String unrecognized = scanPhone.nextLine(); 
       unrecognized = phoneType + unrecognized; 
       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 - 1] = 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.equals(phones[i].getNumber())) { 
      deleteIndex = i; 
     } 
     } 
     if (deleteIndex > -1) { 
     for (int i = deleteIndex; i < phones.length - 1; i++) { 
      phones[i] = phones[i + 1]; 
      phones[phones.length - 1] = null; 
      CellPhone[] newPhones = new CellPhone[phones.length - 1]; 
      phones = newPhones; 
     } 
     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 - 1] = excRecIn; 
    } 

    /** 
    * Returns list of cell phones in phones array. 
    * 
    * @return String 
    */ 
    public String toString() { 
     String result = ""; 
     for (CellPhone phone : phones) { 
     result += phone + "\n"; 
     } 
     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() { 
     DecimalFormat dfmt = new DecimalFormat("$#,000.00"); 
     String summary = "------------------------------" 
     + "\nSummary for " + getName() 
     + "\n------------------------------" 
     + "\nNumber of cell phones: " + phones.length 
     + "\nTexts: " + calculateTotalTexts() 
     + "\nTalk Minutes: " + calculateTotalMinutes() 
     + "\nData: " + calculateTotalData() 
     + "\nHotspot Minutes: " + calculateTotalHotspotMin() 
     + "\niMessages: " + calculateTotalIMessages() 
     + "\nBill Total: " + dfmt.format(calculateTotalBill()); 
     return summary; 
    } 

    /** 
    * Returns string for different rates. 
    * 
    * @return String 
    */ 
    public String rates() { 
     DecimalFormat dfmt = new DecimalFormat("0.00"); 
     String rates = "\n------------------------------\n" 
     + "Rates for " + getName() 
     + "\n------------------------------\n" 
     + "FlipPhone Talk Rate: $" + dfmt.format(FlipPhone.TALK_RATE) 
     + " Text Rate: $" + dfmt.format(FlipPhone.TEXT_RATE) 
     + "\nSmartPhone Talk Rate: $" + dfmt.format(SmartPhone.TALK_RATE) 
     + " Text Rate: $" + dfmt.format(SmartPhone.TEXT_RATE) 
     + " Max Talk Time: " + SmartPhone.MAX_TALK_TIME 
     + "\n iPhone iMessage Rate: $" + dfmt.format(IPhone.IMESSAGE_RATE) 
     + "\n Android Hotspot Rate: $" + dfmt.format(Android.HOTSPOT_RATE) 
     + "\n"; 
     return rates; 
    } 

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

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

    /** 
    * Returns string excluded records. 
    * 
    * @return String 
    */ 
    public String excludedRecordsList() { 
     String excRecList = "------------------------------" 
     + "\nExcluded Records" 
     + "\n------------------------------\n"; 
     for (String unrecPhones : excludedRecords) { 
     excRecList += "\n" + unrecPhones + "\n"; 
     } 
     return excRecList; 
    } 
} 
+0

为什么不使用一个ArrayList? – user2357112

回答

0

请将phones[phones.length - 1] = null;移出for循环。然后,您需要一些代码来复制phonesnewPhones之间的数据,并将这些代码移到for循环之外。

for (int i = deleteIndex; i < phones.length - 1; i++) { 
    phones[i] = phones[i + 1]; 
    // Move three lines of code 
    phones[phones.length - 1] = null; // <= Problem here 
    CellPhone[] newPhones = new CellPhone[phones.length - 1]; 
    // Need some code to copy data 
    phones = newPhones; 
} 

最后,不管怎样,你必须将数据复制到新的数组,所以我觉得你应该从一开始就复制:

CellPhone[] newPhones = new CellPhone[phones.length - 1]; 
int oldIndex = 0, newIndex = 0; 
while (oldIndex < phones.length) { 
    if (oldIndex != deleteIndex) { // Skip copying deleted number 
     newPhones[newIndex++] = phones[oldIndex]; 
    } 

    oldIndex++; 
} 
+0

这是最准确的答案。非常感谢您 – Alvarno

+0

不客气! –

1
CellPhone[] newPhones = new CellPhone[phones.length - 1]; 
phones = newPhones; 

这行声明一个新的数组,但不填充任何价值,他们都是空。您需要遍历newPhones并分配所有值。

CellPhone[] newPhones = new CellPhone[phones.length - 1]; 
for (int i = 0; i < newPhones.length; i++) { 
    newPhones[i] = phones[i]; 
} 
phones = newPhones; 
0

问题应该在循环发生,当你试图设置你的最后一个元素为空时循环和复制:

if (deleteIndex > -1) { 
    for (int i = deleteIndex; i < phones.length - 1; i++) { 
     phones[i] = phones[i + 1]; 
     phones[phones.length - 1] = null; //<====== This line 
     CellPhone[] newPhones = new CellPhone[phones.length - 1]; 
     phones = newPhones; 
    } 
    return true; 
    } 
    else { 
    return false; 
    } 

在任何循环时间,第1行copys到当前指数的下一个元素,但它会是你每次最后一个元素设置为NU问题因为在将它复制到数组的前一个元素之前,会发生这种情况。

我会建议更改为:

if (deleteIndex > -1) { 
     for (int i = deleteIndex; i < phones.length - 1; i++) { 
      phones[i] = phones[i + 1]; 
     } 

     CellPhone[] newPhones = new CellPhone[phones.length - 1]; 
     System.arraycopy(phones, 0, newPhones, 0, phones.length - 1); 
     return true; 
     } 
     else { 
     return false; 
     } 
0
if (deleteIndex > -1) { 
    CellPhone[] tmp = new CellPhone[phones.length - 1]; // smaller array 

    //copy everything before deleteIndex 
    System.arraycopy(phones, 0, tmp, 0, deleteIndex); 

    //copy everything after deleteIndex 
    if (deleteIndex < phones.length - 1) 
    { 
    System.arraycopy(phones, deleteIndex+1, tmp, deleteIndex, 
         phones.length - 1 - deleteIndex); 
    } 

    phones=tmp; // use new smaller array 
} 
0

数组是头痛,我更喜欢的ArrayList;试试这个

public boolean deletePhone(String numberIn) { 
    boolean phoneExists = false; 
    List<String> phoneList = new ArrayList<>(); 
    for (int i = 0; i < phones.length; i++) { 
     if (!numberIn.equals(phones[i].getNumber())) { 
      phoneList.add(phones[i].getNumber()); 
      phoneExists = true; 
     } 
    } 
    phones = phoneList.toArray(new String[phoneList.size()]); 
    return phoneExists; 
} 

如果你不喜欢列表,这里只使用阵列的解决方案:

public boolean deletePhone(String numberIn) { 
    boolean phoneExists = false; 
    String[] newPhones; 
    int newLength = phones.length; 

    for (int i = 0; i < phones.length; i++) { 
     if (numberIn.equals(phones[i].getPhones())) { 
      phones[i] = null; 
      newLength--; 
      phoneExists = true; 
     } 
    } 

    newPhones = new CellPhone[newLength]; 
    for (int i = 0, j = 0; i < phones.length; i++) { 
     if (phones[i] != null) { 
      newPhones[j++] = phones[i]; 
     } 
    } 

    phones = newPhones; 
    return phoneExists; 
}