如何读取两个文件并逐元素对比?附Student类代码片段
Hey there! Let's work through this problem together. You need to read two CSV files with student data (each line looks like 17-995-364,Ruh,Konrad,Julia), compare their elements, and you've got a partial Student class that needs fixing. Let's start by cleaning up that class and building out the rest of the functionality.
First, let's address the syntax and logical issues in your existing Student code. The original has invalid variable naming (quoted identifiers) and a misplaced static method. Instead, we'll build a class that properly represents a student from a CSV line and supports comparison.
import java.util.Objects; public class Student { // Match the 4 fields from your CSV format: ID, Last Name, First Name, Middle Name public String id; public String lastName; public String firstName; public String middleName; // Constructor to initialize all student fields public Student(String id, String lastName, String firstName, String middleName) { this.id = id; this.lastName = lastName; this.firstName = firstName; this.middleName = middleName; } // Static helper to parse a single CSV line into a Student object public static Student fromCsvLine(String line) { // Split the line by commas (note: this works for simple CSVs; use a library like OpenCSV if fields have commas) String[] parts = line.split(","); if (parts.length != 4) { throw new IllegalArgumentException("Invalid student line format: " + line); } // Trim whitespace from each field in case the CSV has extra spaces return new Student( parts[0].trim(), parts[1].trim(), parts[2].trim(), parts[3].trim() ); } // Override equals to compare full student details (adjust if you only want to compare IDs) @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return id.equals(student.id) && lastName.equals(student.lastName) && firstName.equals(student.firstName) && middleName.equals(student.middleName); } // Override hashCode to pair with equals (required for proper Set/Map functionality) @Override public int hashCode() { return Objects.hash(id, lastName, firstName, middleName); } // Optional: For easy printing of student details @Override public String toString() { return String.format("%s, %s %s (%s)", lastName, firstName, middleName, id); } }
Next, let's write a utility method to read all students from a CSV file and store them in a Set (which makes comparison operations faster and handles duplicates automatically).
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashSet; import java.util.List; import java.util.Set; public class StudentFileComparator { public static Set<Student> readStudentsFromFile(String filePath) throws IOException { Set<Student> students = new HashSet<>(); List<String> lines = Files.readAllLines(Paths.get(filePath)); // Skip the header line if your CSV has one (remove this line if there's no header) // lines.remove(0); for (String line : lines) { if (line.isBlank()) continue; // Skip empty lines students.add(Student.fromCsvLine(line)); } return students; } }
Finally, let's add logic to compare the two sets of students, identifying common students, students only present in the first file, and students only present in the second file.
public static void compareStudentFiles(String file1Path, String file2Path) throws IOException { Set<Student> studentsFromFile1 = readStudentsFromFile(file1Path); Set<Student> studentsFromFile2 = readStudentsFromFile(file2Path); // Find students present in both files Set<Student> commonStudents = new HashSet<>(studentsFromFile1); commonStudents.retainAll(studentsFromFile2); // Find students only in the first file Set<Student> onlyInFile1 = new HashSet<>(studentsFromFile1); onlyInFile1.removeAll(studentsFromFile2); // Find students only in the second file Set<Student> onlyInFile2 = new HashSet<>(studentsFromFile2); onlyInFile2.removeAll(studentsFromFile1); // Print results System.out.println("=== Common Students in Both Files ==="); commonStudents.forEach(System.out::println); System.out.println("\n=== Students Only in First File ==="); onlyInFile1.forEach(System.out::println); System.out.println("\n=== Students Only in Second File ==="); onlyInFile2.forEach(System.out::println); } // Test the functionality public static void main(String[] args) { try { compareStudentFiles("students1.csv", "students2.csv"); } catch (IOException e) { System.err.println("Error reading files: " + e.getMessage()); e.printStackTrace(); } }
- If your CSV fields might contain commas (e.g., a name like
Doe, Jr.), replace the simplesplit(",")with a dedicated CSV parser like OpenCSV or Apache Commons CSV to avoid breaking the field separation. - If you only need to compare students by their ID (ignoring name differences), modify the
equalsandhashCodemethods to only use theidfield.
内容的提问来源于stack exchange,提问作者Jo An

