You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java序列化文件去重求和:读取.ser对象并合并重复条目

问题描述

已将Person对象数组写入object.ser文件,需求为读取这些对象后,实现每位人员仅出现一次并累加其对应参与小时数。目前已实现逐行输出单条记录的数值,但不清楚如何完成去重求和的逻辑。

当前代码
public class IOStream {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws ClassNotFoundException {

    Person[] people = new Person[14];
    people[0] = new Professor("Professor", "Issac", "Newton", "Physcis", 6);
    people[1] = new TA("TA", "Marie", "Curie", "Physics", 6);
    people[2] = new Professor("Professor", "Issac", "Newton", "Calculus", 4);
    people[3] = new Student("Student", "Amy", "Adams", "Calculus", 4);
    people[4] = new Student("Student", "Will", "Smith", "Calculus", 4);
    people[5] = new Student("Student", "Brad", "Pitt", "Physics", 6);
    people[6] = new Student("Student", "Will", "Smith", "Physics", 6);
    people[7] = new Professor("Professor", "Dimitri", "Mendeleev", "Chemistry", 6);
    people[8] = new TA("TA", "Carl", "Gauss", "Calculus", 4);
    people[9] = new Student("Student", "Amy", "Adams", "Economics", 3);
    people[10] = new Professor("Professor", "Adam", "Smith", "Economics", 3);
    people[11] = new TA("TA", "Marie", "Curie", "Chemistry", 6);
    people[12] = new Student("Student", "Brad", "Pitt", "Chemistry", 6);
    people[13] = new Student("Student", "Will", "Smith", "Chemistry", 6);

    //WRITING
    try ( ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("object.ser"))) {
        for (int i = 0; i < people.length; i++) {
            out.writeObject(people[i]);
        }
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    //READING INPUT
    try ( ObjectInputStream in = new ObjectInputStream(new FileInputStream("object.ser"))) {
        ObjectOutputStream writer = new ObjectOutputStream(new FileOutputStream("output.ser"));
        Person lol;
        Person [] list;
        int i;
        while ((lol = (Person) in.readObject()) != null) {
            
           writer.writeObject(lol.title + " " + lol.fName + " " + lol.lName + " " + lol.getParticipatingHours(lol.courseHours));
            
        }
    } catch (EOFException i) {
        //System.out.println("lol");
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("Error");
    }       
    try {
        ObjectInputStream reader = new ObjectInputStream(new FileInputStream("output.ser"));
        Object line;
        while ((line = reader.readObject()) != null) {
            System.out.println(line);
        }
    } catch (EOFException i) {
        //System.out.println("lol");
    } catch (IOException e) {
        e.printStackTrace();
    }
   
}
}
当前输出
run:
Professor Issac Newton 4
TA Marie Curie 2
Professor Issac Newton 3
Student Amy Adams 4
Student Will Smith 4
Student Brad Pitt 6
Student Will Smith 6
Professor Dimitri Mendeleev 4
TA Carl Gauss 1
Student Amy Adams 3
Professor Adam Smith 2
TA Marie Curie 2
Student Brad Pitt 6
Student Will Smith 6
解决方案

要实现人员去重并累加小时数,核心是用Map集合存储人员与累计小时数的映射,同时确保Person类能正确判断“同一人”。

步骤1:重写Person类的equals和hashCode方法

判断同一人的依据是title、fName和lName,需在Person类中重写这两个方法(子类若未覆盖,需确保父类实现符合需求):

import java.util.Objects;

public class Person {
    protected String title;
    protected String fName;
    protected String lName;
    protected String course;
    protected int courseHours;

    // 构造方法、getParticipatingHours等已实现的方法...

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(title, person.title) &&
               Objects.equals(fName, person.fName) &&
               Objects.equals(lName, person.lName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(title, fName, lName);
    }
}

步骤2:修改读取逻辑,用Map实现去重求和

替换原代码中读取object.ser的部分,改用HashMap<Person, Integer>存储累计数据,处理完成后再写入输出文件:

// 修改后的READING INPUT部分
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("object.ser"))) {
    // 用Map存储人员与累计小时数的映射
    Map<Person, Integer> personHourMap = new HashMap<>();
    Person currentPerson;

    try {
        while (true) {
            currentPerson = (Person) in.readObject();
            // 计算当前记录的参与小时数
            int currentHours = currentPerson.getParticipatingHours(currentPerson.courseHours);
            // 更新Map:存在则累加,不存在则新增
            personHourMap.put(currentPerson, 
                personHourMap.getOrDefault(currentPerson, 0) + currentHours);
        }
    } catch (EOFException e) {
        // 读取到文件末尾,正常结束循环
    }

    // 将处理后的结果写入output.ser
    try (ObjectOutputStream writer = new ObjectOutputStream(new FileOutputStream("output.ser"))) {
        for (Map.Entry<Person, Integer> entry : personHourMap.entrySet()) {
            Person p = entry.getKey();
            String result = p.title + " " + p.fName + " " + p.lName + " " + entry.getValue();
            writer.writeObject(result);
        }
    }

} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
    System.out.println("Error");
}

步骤3:验证输出

修改后读取output.ser的逻辑不变,最终输出会是每位人员仅出现一次,且数值为累计后的总小时数,例如:

Professor Issac Newton 7
TA Marie Curie 4
Student Amy Adams 7
Student Will Smith 16
Student Brad Pitt 12
Professor Dimitri Mendeleev 4
TA Carl Gauss 1
Professor Adam Smith 2

内容的提问来源于stack exchange,提问作者Avi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:15:55