Java中Hospital类的ArrayList<Department>属性无法返回值问题
问题原因
ArrayList引用传递导致的外部修改影响内部
Java里ArrayList是引用类型,当你把外部的departmentList传给Hospital构造函数时,Hospital类里的departmentList和外部的列表指向同一个内存对象。如果在创建Hospital实例后,你对外部的departmentList执行了clear()、重新赋值(比如departmentList = new ArrayList<>();)这类操作,Hospital内部的列表也会同步变成空。可能遗漏将Hospital实例加入hospitalList
从你给出的步骤2代码看,只创建了hospitalList和hospital对象,但没有执行hospitalList.add(hospital);。如果是循环创建多个Hospital时遗漏这一步,遍历hospitalList拿到的可能是旧的空数据(不过从日志的多条目来看,这条可能性较低,但仍需排查)。
解决方法
方法1:传递列表副本给Hospital构造函数
修改Hospital的构造函数,创建新的ArrayList来接收传入的列表,切断外部列表和内部列表的引用关联:
public Hospital(String hospitalId, String hospitalName, ArrayList<Department> departmentList, int departmentCount) { this.hospitalId = hospitalId; this.hospitalName = hospitalName; // 创建传入列表的副本,避免外部修改影响内部数据 this.departmentList = new ArrayList<>(departmentList); this.departmentCount = departmentCount; }
方法2:保证创建Hospital后不修改原departmentList
如果不需要保留外部的departmentList,可以在循环创建每个Hospital时,都新建一个独立的departmentList,并且创建完成后不对其做清空操作:
// 循环创建每个医院时的代码示例 ArrayList<Department> departmentList = new ArrayList<>(); departmentList.add(new Department(departmentId, hospitalDeptName, hospitalDeptType, subtypeBitFlag, status)); Hospital hospital = new Hospital(hospitalId, hospitalName, departmentList, departmentList.size()); hospitalList.add(hospital); // 必须执行这一步,将医院实例加入列表
方法3:检查并补全Hospital实例添加操作
确认每次创建Hospital对象后,都执行hospitalList.add(hospital);,否则遍历的列表中不会包含新创建的医院数据。
额外优化建议
不要直接暴露Hospital类的成员变量(比如departmentList),改用getter方法返回不可修改的列表,避免外部代码意外修改内部数据:
// 将Hospital的departmentList改为私有 private ArrayList<Department> departmentList = new ArrayList<>(); // 修改get方法,返回不可修改的列表 public List<Department> getDepartmentList() { System.out.println("Returning " + departmentList.size()); return Collections.unmodifiableList(departmentList); }
内容的提问来源于stack exchange,提问作者Joe

