Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何对文本文件中的记录进行排序并存储到二进制文件中?_Java_Sorting_Arraylist - Fatal编程技术网

Java 如何对文本文件中的记录进行排序并存储到二进制文件中?

Java 如何对文本文件中的记录进行排序并存储到二进制文件中?,java,sorting,arraylist,Java,Sorting,Arraylist,我有一个输入文本文件,基本上是一个tsv的人。我需要对所有记录进行排序(按姓、名),然后将所有记录存储到二进制文件中。到目前为止,我所做的是创建一个DataRecord对象,该对象具有所有适当的字段和getter/setters和compareTo。大体上,我有一个DataRecord类型的ArrayList,用于排序 public class DataRecord implements Comparable<DataRecord>{ private String lastName

我有一个输入文本文件,基本上是一个tsv的人。我需要对所有记录进行排序(按姓、名),然后将所有记录存储到二进制文件中。到目前为止,我所做的是创建一个
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();
}

使用
ArrayList
是我的错误吗?

您使用相同的对象引用添加到
ArrayList
中,并在每次迭代时更新它。只需在每次迭代中创建对象的新实例:

while (line != null) {
    DataRecord currentRecord = new DataRecord();
    // rest of the code...
    records.add(currentRecord);
}
//sort the list
作为最佳实践,在尽可能狭窄的范围内声明变量


由于堆空间不足,您可以尝试使用
-Xmx
参数向进程添加更多ram。如果执行该过程的PC中缺少ram,则使用另一种替代方法,如将文件拆分为小块,对每个新文件进行排序,然后在这些文件中的数据之间使用合并排序派生项。

您使用相同的对象引用添加到
ArrayList
中,并在每次迭代时更新它。只需在每次迭代中创建对象的新实例:

while (line != null) {
    DataRecord currentRecord = new DataRecord();
    // rest of the code...
    records.add(currentRecord);
}
//sort the list
作为最佳实践,在尽可能狭窄的范围内声明变量

由于堆空间不足,您可以尝试使用
-Xmx
参数向进程添加更多ram。如果在执行该过程的PC中缺少ram,则使用另一种替代方法,如将文件分割成小块,对每个新文件进行排序,然后在这些文件中的数据之间使用merge sort派生

使用ArrayList是我的错误吗

没有

您的错误是以下一项或两项:

  • 试图同时在内存中保存大文件的信息内容。另一种方法是流式传输数据;e、 g.读取记录、写入记录、读取、记录、写入记录等(当然,这样做的可行性取决于“二进制”文件表示的性质)

  • 正在尝试使用太小的堆运行。java命令文档解释了如何增加堆大小,但显然这种方法存在实际限制

记录在案,这也是一个错误:

    records.add(currentRecord);
如果这样做,您将得到一个列表,其中包含(仅)CSV输入文件中最后一条记录的N个副本。如果要在列表中构建内存中的副本,则需要为每一行创建一个新的
DataRecord
对象


作为记录,从长远来看,更改为
LinkedList
不会有帮助。通过附加到使用
new ArrayList()
创建的列表中而创建的
ArrayList
的最大空间使用量约为引用大小的3倍。对于
LinkedList
而言,空间使用量是引用大小的3倍+每个条目增加2个单词

使用ArrayList是我的错误吗

没有

您的错误是以下一项或两项:

  • 试图同时在内存中保存大文件的信息内容。另一种方法是流式传输数据;e、 g.读取记录、写入记录、读取、记录、写入记录等(当然,这样做的可行性取决于“二进制”文件表示的性质)

  • 正在尝试使用太小的堆运行。java命令文档解释了如何增加堆大小,但显然这种方法存在实际限制

记录在案,这也是一个错误:

    records.add(currentRecord);
如果这样做,您将得到一个列表,其中包含(仅)CSV输入文件中最后一条记录的N个副本。如果要在列表中构建内存中的副本,则需要为每一行创建一个新的
DataRecord
对象



作为记录,从长远来看,更改为
LinkedList
不会有帮助。通过附加到使用
new ArrayList()
创建的列表中而创建的
ArrayList
的最大空间使用量约为引用大小的3倍。对于
LinkedList
来说,空间使用量是引用大小的3倍+每个条目增加2个单词。

您的文件大小是多少?如果您的文件大于可用内存,则必须使用外部排序方法。如果你有足够的内存,你可以增加java堆内存!就像@LuiggiMendonca所说的,我可以想象“\t”中的错误。为什么要切换到“\\t”?在这种情况下,它不会在制表符上拆分,对吗?使用“\\t”或“\t”没有问题。阅读此帖子:。我仍然认为问题在你的档案里。你是否尝试用另一个输入文件运行你的程序?你的文件大小是多少?如果您的文件大于可用内存,则必须使用外部排序方法。如果你有足够的内存,你可以增加java堆内存!就像@LuiggiMendonca所说的,我可以想象“\t”中的错误。为什么要切换到“\\t”?在这种情况下,它不会在制表符上拆分,对吗?使用“\\t”或“\t”没有问题。阅读此帖子:。我仍然认为问题在你的档案里。您是否尝试使用另一个输入文件运行您的程序?执行此操作时,我的heapspace:线程“main”java.lang.OutOfMemoryError:java堆空间抱歉,我认为heapspace错误是在调用集合时发生的。sortNvm,我注释掉了排序,它仍然有一个堆空间错误。这个文件是43.7mb,这是不可能的。错误出现在以下行:
fields=sb.split(“/t”)您是否重写了record类的equal方法?我建议也重写hashCode方法。发布完整的代码。当我这样做时,我仍然会在线程“main”java.lang.OutOfMemoryError:java堆空间中用完heapspace:Exception