0

我这里有一个程序,它应该以长度为 1 的数组开始,允许用户在数组中输入一个条目,然后用户输入的每个条目都将数组的大小加倍以避免java.lang.ArrayIndexOutOfBoundsException错误。按照下面的代码编写方式,如果在第二个用户输入之后,计算机会跳过 else并直接输入“抱歉,数据库已满” 。如果我在第一个else if块中添加newRecords = records ,我会收到java.lang.ArrayIndexOutOfBoundsException错误。

public class PhoneDirectory5 {
    public static void main(String args[]) {
        **PhoneRecord[] records= new PhoneRecord[1];
        int numRecords = 0;**

        // Display list of commands
        System.out.println("Phone directory commands: \n" +
                " a - Add a new phone number\n" +
                " f - Find a new phone number\n" +
                " q - Quit\n" +
                " d - Delete record\n");

        // Read and execute commands
        while (true) {

            // Prompt user to enter a command
            SimpleIO.prompt("Enter command (a, f, d, or q): ");
            String command = SimpleIO.readLine().trim();

            // Determine whether command is "a", "f", "q", or
            // illegal. Execute command if illegal.
            **if (command.equalsIgnoreCase("a"))** {

                // Command is "a". prompt user for name and number,
                // then create a phone record and store it in the
                // database.
                **if (numRecords < records.length) {
                    SimpleIO.prompt("Enter a new name: ");
                    String name = SimpleIO.readLine().trim();
                    SimpleIO.prompt("Enter new phone number: ");
                    String number = SimpleIO.readLine().trim();
                    records[numRecords] =
                            new PhoneRecord(name, number);
                    numRecords++;
                } else if (numRecords == records.length) {
                    PhoneRecord[] newRecords = new PhoneRecord[records.length*2];
                    System.arraycopy(records, 0, newRecords, 0, records.length);
                    SimpleIO.prompt("Enter a new name: ");
                    String name = SimpleIO.readLine().trim();
                    SimpleIO.prompt("Enter new phone number: ");
                    String number = SimpleIO.readLine().trim();
                    newRecords[numRecords] =
                            new PhoneRecord(name, number);
                    numRecords++;**
                } else
                    System.out.println("Sorry, database is full.");

            } else if (command.equalsIgnoreCase("f")) {

                // Command is "f". Prompt user for search key.
                // Search the database for records whose name begins
                // with the search key. Print these names and the
                // corresponding phone numbers.
                SimpleIO.prompt("Enter name to look up: ");
                String key = SimpleIO.readLine().trim().toLowerCase();
                for (int i = 0; i < numRecords; i++) {
                    String name = records[i].getName().toLowerCase();
                    if (name.startsWith(key)) {
                        System.out.println(records[i].getName() + " " +
                                records[i].getNumber());
                        break;
                    } else if (i == numRecords - 1)
                        System.out.println("Sorry, your search did not" +
                                " match any records.");
                }
            } else if (command.equalsIgnoreCase("d")) {
                SimpleIO.prompt("Enter the name of the record to delete: ");
                String key = SimpleIO.readLine().trim().toLowerCase();
                for (int i = 0; i < numRecords; i++) {
                    String name = records[i].getName().toLowerCase();
                    if (name.startsWith(key)) {
                        records[i] = new PhoneRecord("", "");
                        break;
                    } else if (i == numRecords - 1)
                        System.out.println("Sorry, your search did not match" +
                                " any records.");
                }

            } else if (command.equalsIgnoreCase("q")) {
                // Command is "q".. Terminate program
                System.out.println("You have elected to exit the phone directory.");
                return;

            } else {
                // Command is illegal. Display error message.
                System.out.println("Command was not recognized; " +
                        "please enter only a, f, d or q.");
            }
            System.out.println();
        }
    }
}

// Represents a record containing a name and a phone number
class PhoneRecord {
    private String name;
    private String number;

    // Constructor
    public PhoneRecord(String personName, String phoneNumber) {
        name = personName;
        number = phoneNumber;
    }

    // Returns the name stored in the record
    public String getName() {
        return name;
    }

    // Returns the phone number stored in the record
    public String getNumber() {
        return number;
    }
}

话虽如此,当我以这种方式分配新的数组空间时......

else if (numRecords == records.length) {
                    PhoneRecord[] newRecords = new PhoneRecord[records.length*2];
                    for (int i = 0; i < records.length; i++)
                        newRecords[i] = records[i];
                    records = newRecords;
                    SimpleIO.prompt("Enter a new name: ");
                    String name = SimpleIO.readLine().trim();
                    SimpleIO.prompt("Enter new phone number: ");
                    String number = SimpleIO.readLine().trim();
                    newRecords[numRecords] =
                            new PhoneRecord(name, number);
                    numRecords++;

...该程序完全按照我的需要执行,即,将每个用户条目的数组大小加倍,并且从不打印“对不起,但数据库已满”消息。我的问题是,为什么我不能让程序使用.arraycopy方法?任何帮助将非常感激。

当我这样做...

else if (numRecords == records.length) {
                    PhoneRecord[] newRecords = new PhoneRecord[records.length*2];
                    System.arraycopy(records, 0, newRecords, 0, records.length);
                    **newRecords = records;**
                    SimpleIO.prompt("Enter a new name: ");
                    String name = SimpleIO.readLine().trim();
                    SimpleIO.prompt("Enter new phone number: ");
                    String number = SimpleIO.readLine().trim();
                    newRecords[numRecords] =
                            new PhoneRecord(name, number);
                    numRecords++;

...是当我收到 arrayindexoutofbounds 错误时。

4

3 回答 3

3

数组在 Java 中具有固定长度。如果你想要一个动态长度的数组,而不是从头开始编程,你应该使用标准 API 中为你提供的一个:java.util.ArrayList。在此处查看其文档:http: //download.oracle.com/javase/6/docs/api/java/util/ArrayList.html。这个类是 Java 集合 API 的一部分,它是任何 Java 程序员都必须知道的。在Java 教程中学习使用它们。

而不是 a PhoneRecord[],您将拥有一个PhoneRecords 列表:

List<PhoneRecord> records = new ArrayList<PhoneRecord>();

您可以使用添加新记录

records.add(newRecord);

如果需要,由数组列表包裹的数组会自动增长。

您可以使用以下命令访问特定索引

PhoneRecord record = records.get(index);

您还可以像使用数组一样迭代列表:

for (PhoneRecord record : records) {
    // ...
}
于 2011-03-04T08:04:57.360 回答
0

您没有将 newRecords 分配回 System.arraycopy 示例中的记录。

编辑:我同意 JB Nizet。您应该改用 ArrayList。

于 2011-03-04T07:50:55.310 回答
0

在我看来,解决这个问题的最简单方法是为异常创建一个 try/catch。当出现异常时,您将创建新数组。如果你不能让 arraycopy 工作,你总是可以创建一个循环来将元素从旧数组复制到新数组。

于 2011-03-07T01:33:02.233 回答