如何读取和分类文本文件



//我使用java程序读取文本文件(Attrye.txt)并将内容输出到
屏幕,我现在需要编写一个Java程序,该程序按运动员编号读取和对Athere.txt进行排序(然后在屏幕上打印数据。输出可以按上升或下降顺序。

    import java.io.*;
    import java.util.Scanner;

    public class AthleteRecords {
    public static void main(String[] args) throws Exception
    {
      Scanner in = new Scanner(new FileReader("athlete.txt"));
        while (in.hasNextLine())
         {
           System.out.println(in.nextLine());
          }
      }
    }

    //Output file
    Athlete Number: 4233
    First Name: Peter
    Family Name: Brown
    Class 1 
    Position and points awarded for 100m race: 3  50
    Position and points awarded for 200m race: 2  80
    Position and points awarded for 400m race: 1  100
    Class 2
    Position and points awarded for 100m race: 3  50
    Position and points awarded for 200m race: 4  20
    Position and points awarded for 400m race: 2  80
    Athlete Number: 1235
    First Name: Robert
    Family Name: Anderson
    Class 1 
    Position and points awarded for 100m race: 4  20
    Position and points awarded for 200m race: 1  100
    Position and points awarded for 400m race: 2  80
    Class 2
    Position and points awarded for 100m race: 2  80
    Position and points awarded for 200m race: 1  100
    Position and points awarded for 400m race: 3  50
    Athlete Number: 3248
    First Name: Sean
    Family Name: Thompson
    Class 1 
    Position and points awarded for 100m race: 4  20
    Position and points awarded for 200m race: 1  100
    Position and points awarded for 400m race: 2  80
    Class 2
    Position and points awarded for 100m race: 2  80
    Position and points awarded for 200m race: 1  100
    Position and points awarded for 400m race: 3  50

首先,我会创建一个Athlete类,该类容纳您需要的所有信息,例如:

public class Athlete {
    private int id;
    private String firstName;
    private String lastName;
    private List<Race> class1Races;
    private List<Race> class2Races;
    public Athlete() {
        class1Races = new ArrayList<>(4);
        class2Races = new ArrayList<>(4);
    }
    public int getId() {
        return id;
    }
    //...probably more getters, if you need them elsewhere.
    @Override
    public String toString() {
        String idString = Integer.toString(id);
        StringBuilder result = new StringBuilder(60 + idString.length() + firstName.length() + lastName.length() + 52*class1Races.size() + 52*class2Races.size());
        result.append("Athlete Number: ");
        result.append(idString);
        result.append("nFirst Name: ");
        result.append(firstName);
        result.append("nFamily Name: ");
        result.append(lastName);
        result.append("nClass1n");
        for(Race race : class1Races) {
            result.append(race.toString());
            result.append("n");
        }
        result.append("Class2n");
        for(Race race : class2Races) {
            result.append(race.toString());
            result.append("n");
        }
        return result.toString();
    }
    void setId(int id) {
        this.id = id;
    }
    void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    void setLastName(String lastName) {
        this.lastName = lastName;
    }
    void addRaceClass1(Race race) {
        class1Races.add(race);
    }
    void addRaceClass2(Race race) {
        class2Races.add(race);
    }
}
public class Race { //And accompanying Race class to hold information about a race.
    private String name;
    private int position;
    private int points;
    public Race(String name,int position,int points) {
        this.name = name;
        this.position = position;
        this.points = points;
    }
    @Override
    public String toString() {
        String positionString = Integer.toString(position);
        String pointsString = Integer.toString(points);
        StringBuilder result = new StringBuilder(42 + name.length() + positionString.length() + pointsString.length());
        result.append("Position and points awarded for ");
        result.append(name);
        result.append(" race: ");
        result.append(positionString);
        result.append("  ");
        result.append(pointsString);
        return result.toString();
    }
    //...probably some getters, if you need them elsewhere.
}

接下来,您将需要解析该文件。我不知道完整的文件规范,但是通过您的示例,我可以猜到:

private List<Athlete> parseAthletes(String filename) throws IOException {
    List<Athlete> result = new ArrayList<>(12);
    BufferedReader br = new BufferedReader(new FileReader(filename));
    Athlete athlete = null;
    int currentClass = 0;
    String line = null; //Loop as long as there are input lines.
    while((line = br.readLine()) != null) { //Sets the line variable and reads it all at once!
        if(line.startsWith("Athlete Number: ")) {
            athlete = new Athlete();
            result.add(athlete);
            athlete.setId(Integer.parseInt(line.substring(16))); //Throws NumberFormatException if not a number.
            currentClass = 0;
        } else if(line.startsWith("First Name: ")) {
            if(athlete == null) //No Athlete Number was seen yet.
                throw new IOException("Wrong format!");
            athlete.setFirstName(line.substring(12));
        } else if(line.startsWith("Family Name: ")) {
            if(athlete == null)
                throw new IOException("Wrong format!");
            athlete.setLastName(line.substring(13));
        } else if(line.startsWith("Class ")) {
            if(athlete == null)
                throw new IOException("Wrong format!");
            currentClass = Integer.parseInt(line.substring(6)); //Throws NumberFormatException if not a number.
        } else if(line.startsWith("Position and points awarded for ") && line.contains(" race: ")) {
            if(athlete == null || (currentClass != 1 && currentClass != 2))
                throw new IOException("Wrong format!"); //Need to have seen an athlete as well as a class number.
            String raceName = line.substring(32,line.indexOf(" race: ",32));
            line = line.substring(line.indexOf(" race: ",32) + 7); //Trim off the start.
            int position = Integer.parseInt(line.substring(0,line.indexOf("  ")));
            int points = Integer.parseInt(line.substring(line.indexOf("  ") + 2));
            Race race = new Race(raceName,position,points);
            if(currentClass == 1)
                athlete.addRaceClass1(race);
            else //We already know class must be 2.
                athlete.addRaceClass2(race);
        }
    }
    return result;
}

,如果班级编号可能仅仅是1和2,则可能需要列出种族列表,也可以通过缓存查询索引来提高效率,但通常性能并不是真正的问题这些文件解析器;如果这是一个问题,您最好尝试并行完成阅读并使用二进制格式。

最后,要按ID对列表进行排序,您可以使用Comparator。您甚至不需要为其创建一个全新的课程,您只能匿名定义Comparator的实例:

List<Athlete> athletes = parseAthletes("athlete.txt");
Comparator<Athlete> athletesById = new Comparator<Athlete>() {
    @Override
    public int compare(Athlete a,Athlete b) {
        return Integer.compare(a.getId(),b.getId());
    }
}
Collections.sort(athletes,athletesById);
for(Athlete athlete : athletes) {
    System.out.println(athlete.toString());
}

此比较器定义要比较两个Athlete s,只需要比较ID。

我可能在这里和那里曾在这里和一个逻辑错误中发出错别字,因此请彻底测试此代码,或者更好,请受到其启发,然后自己编写代码。

最新更新