Проблема увеличения массива в Java - PullRequest
0 голосов
/ 04 марта 2011

У меня здесь есть программа, которая должна начинаться с массива длины 1, позволяющего пользователю сделать запись в массиве, а затем удваивать размер массива с каждой записью, которую пользователь делает, чтобы избежать java.lang.ArrayIndexOutOfBoundsException ошибка. При написании кода ниже, компьютер пропускает , в противном случае, если после второго ввода пользователя, и сразу переходит к Извините, база данных заполнена . Если я добавлю newRecords = records в первый иначе, если блок, я получу java.lang.ArrayIndexOutOfBoundsException error.

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++;

... это когда я получаю сообщение об ошибке извлечения массива.

Ответы [ 3 ]

4 голосов
/ 04 марта 2011

Массивы имеют фиксированную длину в Java.Если вам нужен массив динамической длины, а не программировать его с нуля, вам следует использовать тот, который указан для вас в стандартном API: java.util.ArrayList.Посмотрите его документацию здесь: http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html. Этот класс является частью API коллекций Java, который должен знать любой программист на Java.Научитесь использовать их в руководстве по Java .

Вместо PhoneRecord[] у вас будет список PhoneRecord s:

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

Вы можетедобавьте новую запись с помощью

records.add(newRecord);

, и массив, обернутый списком массивов, будет автоматически увеличиваться при необходимости.

И вы можете получить доступ к определенному индексу с помощью

PhoneRecord record = records.get(index);

Вы также можете выполнять итерации по списку, как если бы вы использовали массив:

for (PhoneRecord record : records) {
    // ...
}
1 голос
/ 07 марта 2011

Мне кажется, что самый простой способ обойти это - создать try / catch для исключения.Когда приходит исключение, вы создаете новый массив.если вы не можете заставить работать arraycopy, вы всегда можете сделать цикл для копирования элементов из старого массива в новый.

1 голос
/ 04 марта 2011

Вы не присвоили newRecords обратно записям в примере System.arraycopy.

редактировать: я согласен с JB Nizet. Вместо этого вы должны использовать ArrayList.

...