【发布时间】:2015-09-02 22:48:30
【问题描述】:
我有一个输入文本文件,它基本上是一群人。我需要对所有记录进行排序(按姓氏、名字),然后将所有记录存储到二进制文件中。到目前为止,我所做的是创建一个 DataRecord 对象,该对象具有所有适当的字段和 getter/setters 和 compareTo。总的来说,我有一个DataRecord 类型的ArrayList 用于排序目的。
public class DataRecord implements Comparable<DataRecord>{
private String lastName, firstName, middleName, suffix, cityOfBirth;
private int monthOfBirth, dayOfBirth, yearOfBirth;
private char gender;
//getters
public String getLastName() { return this.lastName;}
public String getFirstName() { return this.firstName;}
public String getMiddleName() { return this.middleName;}
public String getSuffix() { return this.suffix;}
public String getCityOfBirth() { return this.cityOfBirth;}
public int getMonthOfBirth() { return this.monthOfBirth;}
public int getDayOfBirth() { return this.dayOfBirth;}
public int getYearOfBirth() { return this.yearOfBirth;}
public char getGender() { return this.gender;}
//setters
public void setLastName(String lastName) { this.lastName = lastName;}
public void setFirstName(String firstName) { this.firstName = firstName;}
public void setMiddleName(String middleName) { this.middleName = middleName;}
public void setSuffix(String suffix) { this.suffix = suffix;}
public void setCityOfBirth(String cityOfBirth) { this.cityOfBirth = cityOfBirth;}
public void setMonthOfBirth(int monthOfBirth) { this.monthOfBirth = monthOfBirth;}
public void setDayOfBirth(int dayOfBirth) { this.dayOfBirth = dayOfBirth;}
public void setYearOfBirth(int yearOfBirth) { this.yearOfBirth = yearOfBirth;}
public void setGender(char gender) { this.gender = gender;}
public DataRecord(){
}
//constructor to make copy of record passed in
public DataRecord(DataRecord copyFrom){
this.lastName = copyFrom.getLastName();
this.firstName = copyFrom.getFirstName();
this.middleName = copyFrom.getMiddleName();
this.suffix = copyFrom.getSuffix();
this.monthOfBirth = copyFrom.getMonthOfBirth();
this.dayOfBirth = copyFrom.getDayOfBirth();
this.yearOfBirth = copyFrom.getYearOfBirth();
this.gender = copyFrom.getGender();
this.cityOfBirth = copyFrom.getCityOfBirth();
}
@Override
public int compareTo(DataRecord arg0) {
// TODO Auto-generated method stub
int lastNameCompare;
//check if the last names are the same, if so return the first name comparison
if ((lastNameCompare = this.getLastName().compareTo(arg0.getLastName())) == 0){
return this.getFirstName().compareTo(arg0.getFirstName());
}
//otherwise return the last name comparison
return lastNameCompare;
}
public String toString(){
return this.getLastName() + ' ' + this.getFirstName();
}
}
public class IOController {
public static void main(String[] args) throws IOException {
File inputFile; // input file
RandomAccessFile dataStream = null; // output stream
ArrayList<DataRecord> records = new ArrayList<DataRecord>();
BufferedReader reader = new BufferedReader(new FileReader(args[0]));
try {
String sb;
String line = reader.readLine();
String[] fields;
// loop through and read all the lines in the input file
while (line != null) {
DataRecord currentRecord = new DataRecord();
// store the current line into a local string
sb = line;
// create an array of all the fields
fields = sb.split("\t");
// set the fields for the DataRecord object
currentRecord.setLastName(fields[0]);
currentRecord.setFirstName(fields[1]);
// check other fields exist
if (fields.length >= 3) {
currentRecord.setMiddleName(fields[2]);
currentRecord.setSuffix(fields[3]);
currentRecord.setMonthOfBirth(Integer.parseInt(fields[4]));
currentRecord.setDayOfBirth(Integer.parseInt(fields[5]));
currentRecord.setYearOfBirth(Integer.parseInt(fields[6]));
currentRecord.setGender(fields[7].charAt(0));
currentRecord.setCityOfBirth(fields[8]);
}
// add the current record to the array list of records
records.add(currentRecord);
line = reader.readLine();
}
} finally {
reader.close();
//Collections.sort(records);
}
for (int i = 0; i < 5; i++) {
System.out.println(records.get(i));
}
}
}
我的问题是,如果我使用临时的DataRecord(名为currentRecord)来读取字段,然后添加到ArrayList,我在ArrayList 的每条记录中都有所有相同的数据。如果我将该数据复制到另一个 DataRecord 对象(使用我传入 DataRecord 的构造函数),我会用完堆空间。
records.add(new DataRecord(currentRecord));
line = reader.readLine();
是我使用ArrayList 的错误吗?
【问题讨论】:
-
你的文件有多大?如果您的文件大于可用内存,您将不得不使用外部排序方法。 en.wikipedia.org/wiki/External_sorting如果你有足够的内存,你可以增加java堆内存。
-
代码看起来不错!就像@LuiggiMendonca 所说,我想象“\t”中的错误。
-
为什么要切换到“\\t”?在这种情况下,它不会在制表符上拆分,对吗?
-
使用“\\t”或“\t”没问题。阅读这篇文章:stackoverflow.com/questions/3762347/…。我仍然认为问题出在您的文件中。您是否尝试使用另一个输入文件运行您的程序?