在java中如何按顺序对文件进行排序
我有一个方法,可以读取文本文件并写入临时文本文件(用于重写),然后删除旧的文本文件。此函数用于读取、排序和重写 我有这个方法:在java中如何按顺序对文件进行排序,java,file,sorting,Java,File,Sorting,我有一个方法,可以读取文本文件并写入临时文本文件(用于重写),然后删除旧的文本文件。此函数用于读取、排序和重写 我有这个方法: public void sortFile() { String line; int count = 0; int min; int j=0; try { BufferedReader asd = new BufferedReader(new FileReader(list)); while((line=as
public void sortFile()
{
String line; int count = 0; int min;
int j=0;
try
{
BufferedReader asd = new BufferedReader(new FileReader(list));
while((line=asd.readLine()) != null)
{
count++; //count how many lines
}
Object temp,temp1,temp2,temp3;
String names[] = new String[count];
Double timeInd[] = new Double[count];
String scores[] = new String[count];
String difficulty[] = new String[count];
while((line=asd.readLine()) != null)
{
String var[] = line.split("-");
names[j] = var[0];
timeInd[j]=Double.parseDouble(var[1]);
scores[j] = var[2];
difficulty[j] = var[3];
j++;
}
asd.close();
if(count!=1)
{
for(int i=0; i<count; i++) //Selection sort
{
min=i;
for(int a=1; a<count ; a++)
{
if(timeInd[a]<timeInd[min]) min=a;
}
//swap values;
temp=names[i];
temp1=timeInd[i];
temp2=scores[i];
temp3=difficulty[i];
////////
names[i] = names[min];
timeInd[i]= timeInd[min];
scores[i] = scores[min];
difficulty[i] = difficulty[min];
/////////
names[min] = (String) temp;
timeInd[min] = (Double) temp1;
scores[min] = (String) temp2;
difficulty[min] = (String) temp3;
}
}
//rewrite the new sorted values;
PrintWriter write = new PrintWriter(new FileWriter(tempo,true));
for(int i=0;i<count;i++)
{
write.println(names[i]+"-"+timeInd[i]+"-"+scores[i]+"-"+difficulty[i]);
}
write.close();
list.delete();
tempo.renameTo(list);
}catch(Exception e){};
}
我把它们分成四份。正如您可以在我上面的代码中查看的那样。第一个是名字,第二个是时间,第三个是分数,第四个是难度。现在我的问题是我想把我的文件按升序排序,这种排序的基础是时间。谁跑得最快,谁当然是最快的。顺便说一下,我使用了选择排序。然而如果我的文本文件只有一行值。与上面的示例内容类似:
myName-12.999-100-Easy
新重写的文本文件现在将具有:
null-null-null-null
即使我用我的
如果(计数!=1)
但是如果我有多个像这样的记录:
hisName-14.542-100-Easy
herName-1.432-100-Easy
它不会产生null,但会产生相同的结果。它还没有分类。为什么?我不知道这背后的逻辑问题是什么。我希望你能帮助我。干杯。第一点
您正在完整阅读内容一次
while((line=asd.readLine()) != null)
{
count++; //count how many lines
}
但是,如果不重置流,就无法在BufferedReader上真正使用它,因为它只能重置回一定数量的字节(缓冲区大小)。如果您的文件大于该值,则无法工作,请尝试再次读取该文件。这是你永远无法做到的。因为读取器已经到达文件的末尾
while((line=asd.readLine()) != null)
{
count++; //added now ----> 1
String var[] = line.split("-");
names[j] = var[0];
timeInd[j]=Double.parseDouble(var[1]);
scores[j] = var[2];
difficulty[j] = var[3];
j++;
}
因此可以在第二个while循环中添加计数。请参见第二个while循环中的注释
第二点
不要抑制异常:
catch(Exception e){};
修复以上两个问题将有助于调试代码
关于代码审查,您可以进行以下更改,以使运行更加顺利
创建class.structure以表示单行读取:
class Data implements Comparable
{
String name;
Double timeInd;
String score;
String difficulty;
}
迭代文件中的每一行时,创建一个数据对象并填充其属性
循环完成后,您将有一个列表
编写一个比较器,根据两个数据对象的timeid比较它们
现在使用
排序(List,comparator),对列表进行排序。迭代排序后的数据列表,并将属性写入新文件,无论您希望采用何种格式
实施说明:此实施是一种稳定的、自适应的,
迭代合并排序,需要的比较次数远少于n个lg(n)
当输入数组部分排序时
输入数组为空时传统mergesort的性能
随机排列的
无论是从效率还是从代码可维护性方面来说,您的选择排序都不是一种很好的方法
最好的做法是将
字符串
对象读入列表
,然后使用列表上的集合。排序
,提供一个比较器
,比较两个字符串
并根据字符串
内的时间决定它们的顺序。这意味着你所需要编码的就是提取时间并比较两次的位;其余的都将由JDK(高效地)处理。Wow。我试试这个。ThanksI正在计算有多少行,这样我就可以在下面的数组中给出一个固定值。如果BufferedReader不是那么好。我可以用扫描器来读取吗?不可以。既然一次就可以读取文件,为什么还要读取两次呢。仔细阅读,BufferedReader reset()不是首选项。您应该使用缓冲读取器来读取字符流,但要高效地执行。这就是我的观点。我在考虑Collections.sort,但是如果我选择Collections.sort(timeIndicator),唯一排序的部分是timeInd,但是其余的呢?名字、分数和难度?你能给我一个简单的提示吗?你需要创建一个比较器
,它的比较
方法根据所有的值按顺序进行比较。@Roch见下面我的答案。谢谢@BatScream和chiatic Security。我得试试这个。干杯
class Data implements Comparable
{
String name;
Double timeInd;
String score;
String difficulty;
}