Java中的数组增广问题
我这里有一个程序,应该以长度为 1 的数组开始,允许用户在数组中输入一个条目,然后用户输入的每个条目将数组的大小加倍,以避免 java.lang.Error 错误。 lang.ArrayIndexOutOfBoundsException 错误。按照下面代码的编写方式,计算机在第二次用户输入后会跳过else if,直接输入对不起,数据库已满。如果我在第一个 else if 块中添加 newRecords = reports,则会收到 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 错误时。
I have here a program that is supposed to begin with an array of length 1, allow the user to make an entry into the array, and then double the size of the array with each entry the user makes to avoid an java.lang.ArrayIndexOutOfBoundsException error. The way the code is written below, the computer skips else if after the second user entry and goes straight for Sorry, database is full. If I add newRecords = records in the first else if block, I get the 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;
}
}
All this being said, when I allocated new array space in this fashion...
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++;
...the program did exactly what I needed it to do, namely, double the size of the array with each user entry and never print the "Sorry, but the database is full" message. My question is, why can't I get the program to work with the .arraycopy method? Any help would be much appreciated.
When I do this...
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++;
...is when I get the arrayindexoutofbounds error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Java 中数组的长度是固定的。如果您想要一个动态长度的数组,而不是从头开始编程,您应该使用标准 API 中为您提供的数组:java.util.ArrayList。在此处查看其文档: http://download.oracle .com/javase/6/docs/api/java/util/ArrayList.html。该类是 Java 集合 API 的一部分,这是任何 Java 程序员都必须了解的。在Java 教程中学习如何使用它们。
您将拥有一个
PhoneRecord
列表,而不是PhoneRecord[]
:您可以添加一条新记录
,并且数组列表包含的数组将在需要时自动增长。
您可以使用以下命令访问特定索引。
您还可以像使用数组一样在列表上进行迭代:
Arrays have a fixed length in Java. If you want a dynamic-length array, rather than programming it from scratch, you should use the one given for you in the standard API : java.util.ArrayList. Look at its documentation here : http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html. This class is part of the Java collections API, which is a must-know for any Java programmer. Learn to use them in the Java tutorial.
Rather than a
PhoneRecord[]
, you would have a list ofPhoneRecord
s :You can add a new record with
and the array wrapped by the array list will automatically grow if needed.
And you can access to a specific index with
You can also iterate on the list as you would with an array :
您没有将 newRecords 分配回 System.arraycopy 示例中的记录。
编辑:我同意 JB Nizet 的观点。你应该使用 ArrayList 来代替。
You didn't assign newRecords back to records in the System.arraycopy example.
edit: I agree with JB Nizet. You should use ArrayList instead.
在我看来,解决这个问题的最简单方法是为异常创建一个 try/catch。当异常出现时,您创建新数组。如果您无法使 arraycopy 工作,您始终可以创建一个循环将元素从旧数组复制到新数组。
It seems to me the easiest way to get around this is creating a try/catch for the exception. When exception comes in you create the new array. if you cant get the arraycopy to work you can always make a loop to copy elements from old array to new one.