简体   繁体   English

如何对文本文件进行排序并使用Java保存?

[英]How to sort a text file and save it using java?

I have been asked to make a quiz and in the end of the quiz, what I want to keep are in two separate arrays names[] and scores[]. 我被要求做一个测验,在测验的最后,我要保留的是两个单独的数组name []和scores []。 I have been asked to save the scores in a file using input and output. 我被要求使用输入和输出将分数保存在文件中。 I have managed to do everything and successfully output the results and save it into the files (eg highscores.txt) 我已设法做所有事情并成功输出结果并将其保存到文件中(例如highscores.txt)

the results are saved like this: 结果保存如下:

4
name10
name5
name4
name2

the first line indicates how many scores there are in the file as every person who plays the quiz has their score saved. 第一行表示文件中有多少个分数,因为每个参加测验的人都保存了分数。 What I am struggling to do is sort the scores to be placed in order of highest to lowest. 我正在努力做的是按照最高到最低的顺序对分数进行排序。

I have tried sorting the scores before they are saved in the file but the older scores in the file will not be sorted anymore. 我已经尝试过对分数进行排序,然后再将它们保存在文件中,但是文件中较旧的分数将不再进行排序。 Example: 例:

8 
newname10
newname9 
newname8
newname7
name10
name5
name4
name2

im only a beginner so go easy... 我只是一个初学者,所以请轻松...

What you should do is to create class Person which implements Comparable<Person> and if you are little bit lazy and the amount of data is not large Serializable too. 您应该做的是创建实现Comparable<Person> class Person ,如果您有点懒并且数据量也不大,则可Serializable

Then put everything inside TreeSet<Person> and write methods which serialize the TreeSet and deserialize it too. 然后将所有内容放入TreeSet<Person>并编写一些方法来序列化TreeSet并反序列化它。

Like this: 像这样:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.TreeSet;

public class Person implements Comparable<Person>, Serializable {
    private String name;
    private int score;

    public Person(String name, int score) {
        this.name = name;
        this.score = score;
        addPerson(this);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public int compareTo(Person o) {
        return score - o.score;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", score=" + score + "]";
    }

    private static TreeSet<Person> classExtension = new TreeSet<Person>();

    private static void addPerson(Person person) {
        classExtension.add(person);
    }

    private static void removePerson(Person person) {
        classExtension.remove(person);
    }

    private static void showExtension() {
        for (Person person : classExtension)
            System.out.println(person);
    }

    public static void serialize() {

        FileOutputStream fos = null;
        ObjectOutputStream oos = null;

        try {
            fos = new FileOutputStream("Person.ser");
            oos = new ObjectOutputStream(fos);

            oos.writeObject(classExtension);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                if (oos != null)
                    oos.close();
            } catch (IOException e) {
            }
            try {
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
            }
        }
    }

    public static void deserialize(){

         FileInputStream fis = null;
         ObjectInputStream ois = null;
         try {
           fis = new FileInputStream("Person.ser"); 
           ois = new ObjectInputStream(fis); 

         classExtension =  (TreeSet<Person>) ois.readObject(); 

         } catch (FileNotFoundException e) {
           e.printStackTrace();
         } catch (IOException e) {
           e.printStackTrace();
         } catch (ClassNotFoundException e) {
           e.printStackTrace();
         } finally {
           // zasoby zwalniamy w finally
           try {
             if (ois != null) ois.close();
           } catch (IOException e) {}
           try {
             if (fis != null) fis.close();
           } catch (IOException e) {}
         }
    }

}

Well, because you don't use any kind of formatting to easily distinguish between username and score (eg: [username]:[score]) you've the problem to separate these two information from each other afterwards. 好吧,因为您没有使用任何格式来轻松区分用户名和得分(例如[username]:[score]),所以问题在于以后将这两个信息彼此分开。

Anyhow - you need to load the data and reorder them trying to separate the username from the score. 无论如何-您需要加载数据并对其重新排序,以尝试将用户名与乐谱分开。 Read the file line my line and split the name from the score using regexp (in hope that the user name contains only letters): Pattern.compile("(\\w+)(\\d+)") . 阅读文件行my并使用regexp(希望用户名仅包含字母)从乐谱中拆分名称: Pattern.compile("(\\w+)(\\d+)") You can then use Matcher to get group 1 (the Name) and group 2 (the score). 然后,您可以使用Matcher获得组1(名称)和组2(分数)。 Then you can compare the score and reorder the List 然后您可以比较分数并重新排列列表

This little program should do the Job. 这个小程序应该可以完成任务。

Bear in mind that this really just sorts a text-file. 请记住,这实际上只是对文本文件进行排序。 If you need further processing according to your problem, modify it. 如果根据您的问题需要进一步处理,请对其进行修改。

public class LineReader {
    public static void main(String[] args) {
        String file = args[0];
        List<String> _list = new ArrayList<String>();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            for (String line; (line = br.readLine()) != null;) {
                _list.add(line);
            }
        } catch (Exception ex) {
        }
        java.util.Collections.sort(_list, String.CASE_INSENSITIVE_ORDER);
        try(FileWriter writer = new FileWriter(file)) {
            for (String str : _list) {
                writer.write(str + "\n");
            }
            writer.close();
        } catch (IOException ex) {
        }
    }
}

If you're already able to sort the results before writing them to the file, why don't you read all the file before updating It? 如果您已经能够在将结果写入文件之前对结果进行排序,那么为什么不在更新文件之前先读取所有文件呢? Then you can put the old data stored in your data structure with the new data,and sort them alla together. 然后,您可以将存储在数据结构中的旧数据与新数据放在一起,并将它们全部排序。 Then you should overwrite the old file with the data you already have. 然后,您应该使用已有的数据覆盖旧文件。

This way could be expensive if your file has a lot of record. 如果您的文件有很多记录,这种方法可能会很昂贵。

The best way could be to use a collection that keep items in order. 最好的方法可能是使用使项目保持秩序的集合。 Take a look to PriorityQueue class. 看一下PriorityQueue类。 Then just store it into the file,and load It before adding new elements. 然后只需将其存储到文件中,然后在添加新元素之前加载它。 You can write the PriorityQueue to a file using an ObjectOutputStream and read it back with an ObjectInputStream. 您可以使用ObjectOutputStream将PriorityQueue写入文件,然后使用ObjectInputStream读回该文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM