如何将包含字符串和整数的文件读入 ArrayList 并按整数排序?

How to read a file containing strings and integers into an ArrayList and sort by integer?

我正在尝试从包含按行组织的姓名和成绩列表的文本文件中读取,即:

大卫·史密斯 84

苏珊·波特 100

...

然后将它们(按行)存储在 ArrayList 中,并使用选择排序算法按学生成绩对 ArrayList 进行排序,但是我尝试了多种不同的编码方式,每次编辑似乎都会提示另一个错误(我对编程非常陌生)。这是我目前拥有的:

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

public class Grades {
    private static void sort(ArrayList<String> list) {
        int pFill;
        int pTest;
        int pSmallest;
        String temp;
        for (pFill = 0; pFill < list.size(); pFill++) {
            pSmallest = pFill;
            for (pTest = pFill + 1; pTest < list.size(); pTest++) {
                if (pTest < pSmallest) {
                    pSmallest = pTest;
                }
            }
            temp = list.get(pSmallest);
            list.set(pSmallest, list.get(pFill));
            list.set(pFill, temp);
        }
    } 

    public static void main(String[] args){
        ArrayList<String> list = new ArrayList<>();
        String fileName = "students.txt";
        try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
            while(input.ready()){
                list.add(input.readLine());
            }
            input.close();
            sort(list);
            System.out.println(list);
        } catch (IOException e){
                System.out.println(e.getMessage());
        }
    }
}

如果您声明一个具有 2 个字段 nameageStudent class,这将很容易。你可以让 Student class 实现 Comparable 并根据等级进行比较。它看起来像这样:

public class Student implements Comparable<Student> {
    private final String name;
    private final int grade;
    public Student(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }
    @Override
    public int compareTo(Student s) {
        return Integer.compare(this.grade, grade);
    }
}

要填充 Student 对象,您需要拆分 String 并提取姓名和成绩,然后调用 new Student(name, grade).

在您的 sort 方法中,您可以传递一个 List<Student>,您可以在其中通过调用 s1.compareTo(s2).[=23= 之类的方法来比较 2 个学生(如 Student implements Comparable<Student>) ]

获得学生名单后。您可以使用 Comparator 来执行此操作。

List<Student> sorted=list.sort(Comparator.comparing(p-> p.getGrade()));

或使用流api

List<Person> result =list.stream().sorted((p1, p2)>p1.getGrade().compareTo(p2.getGrade())).collect(Collectors.toList());

您可以创建一个学生对象来分别保存姓名和成绩。将所有数据添加到列表后,您可以使用 Comparator 直接使用 list.sort() 方法,但在您的情况下,您想要编写选择排序,这就是为什么您必须编写另一种方法来进行选择排序的原因.

package com.stackovflow.problems;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class Grades {

        public static void main(String[] args){
            ArrayList<Student> list = new ArrayList<>();
            String fileName = "students.txt";
            try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
                while(input.ready()){
                    String line = input.readLine().trim();
                    String name = line.substring(0,line.lastIndexOf(' '));
                    int grade = Integer.parseInt(line.substring(line.lastIndexOf(' ')+1));
                    list.add(new Student(name, grade));
                }
                input.close();
                selectionSort(list);
                System.out.println(list);
            } catch (IOException e){
                    System.out.println(e.getMessage());
            }
        }

        private static void selectionSort(ArrayList<Student> list) {
            int pFill;
            int pTest;
            int pSmallest;
            Student temp;
            for (pFill = 0; pFill < list.size(); pFill++) {
                pSmallest = pFill;
                for (pTest = pFill + 1; pTest < list.size(); pTest++) {
                    Student pTestStudent = list.get(pTest);
                    Student pSmallestStudent = list.get(pSmallest);
                    if (pTestStudent.getGrade() < pSmallestStudent.getGrade()) {
                        pSmallest = pTest;
                    }
                }
                if(pSmallest!=pFill) {
                    temp = list.get(pSmallest); 
                    list.set(pSmallest, list.get(pFill));
                    list.set(pFill, temp);
                }
            }

        }
    }

//This class is to hold line data in your students.txt file
class Student{
    private String name;
    private int grade;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getGrade() {
        return grade;
    }
    public void setGrade(int grade) {
        this.grade = grade;
    }
    public Student(String name, int grade) {
        super();
        this.name = name;
        this.grade = grade;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", grade=" + grade + "]";
    }

}

在同一文件夹中创建一个单独的 Student.java 文件来保存学生 class:

public class Student {
    private final String name;
    private final int grade;
    public Student(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }
    public String getName(){
        return name;
    }
    public int getGrade(){
        return grade;
    }
}

然后将每一行按space拆分,将第一个标记设置为姓名,最后一个标记设置为年级,然后使用比较器对学生对象的ArrayList进行排序:

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


public class Grades {
    private static ArrayList<Student> sort(ArrayList<String> list) {

        ArrayList<Student> students = new ArrayList<Student>();

        String name = "";
        int grade;

        for (String line : list) {
            String[] splitted = line.split("\s+");

            for(int i = 0;i< splitted.length-1;i++){
                name += splitted[i] + " ";
            }
            grade = Integer.parseInt(splitted[splitted.length-1]);
            students.add(new Student(name,grade));
            name = "";

        }
        students.sort(Comparator.comparing(student-> student.getGrade()));

        return students;

    } 

    public static void main(String[] args){
        ArrayList<String> list = new ArrayList<>();
        String fileName = "students.txt";
        try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
            while(input.ready()){
                list.add(input.readLine());
            }
            input.close();
            ArrayList<Student> sortedStudents = sort(list);

            for (Student currentStudent : sortedStudents) 
                System.out.println(currentStudent.getName() + currentStudent.getGrade());                


        } catch (IOException e){
                System.out.println(e.getMessage());
        }
    }
}