修改排班列表特定元素Pair值时其他元素同步变更的技术问题
问题根源:共享集合引用导致的意外同步修改
你遇到的这个问题其实很典型——所有员工的排班集合指向了同一个内存对象,所以改一个就会全跟着变。
咱们看你生成dutyList的代码:
val dateShiftPair = ArrayList<Pair<String, String>>() dateList.forEach {date -> dateShiftPair.add(Pair(date, "E")) } staffList.forEach {staff -> dutyList.add(Triple(list.indexOf(staff), staff.name!!, dateShiftPair)) }
这里你只创建了一个dateShiftPair集合,然后把这个集合的引用重复添加到每个员工的Triple里。也就是说,所有员工的third字段都指向同一个ArrayList实例,本质上是共享同一份数据。所以你修改任何一个员工的排班项,其他员工的对应位置自然也会跟着变——因为它们本来就是同一个集合里的元素。
解决方案:给每个员工创建独立的排班集合
解决思路很简单:每个员工都拥有自己的dateShiftPair集合,而不是共享同一个。把集合的创建逻辑放到staffList的循环里就行:
val dutyList = ArrayList<Triple<Int, String, ArrayList<Pair<String, String>>>>() staffList.forEach { staff -> // 每个员工循环时,都新建一个专属的排班集合 val dateShiftPair = ArrayList<Pair<String, String>>() dateList.forEach { date -> dateShiftPair.add(Pair(date, "E")) } dutyList.add(Triple(list.indexOf(staff), staff.name!!, dateShiftPair)) }
或者用更简洁的Kotlin风格写法(用map替代循环):
val dutyList = staffList.mapIndexed { index, staff -> // 为每个员工生成独立的排班Pair列表 val dateShiftPairs = dateList.map { Pair(it, "E") } as ArrayList Triple(index, staff.name!!, dateShiftPairs) } as ArrayList<Triple<Int, String, ArrayList<Pair<String, String>>>>
这样一来,每个员工的third字段都是独立的ArrayList实例,修改其中一个员工的排班项时,只会影响该员工自己的数据,不会波及其他员工了。
另外补充一点:Kotlin里的Pair是不可变的数据类(属性都是val),你现在通过创建新Pair替换集合元素的写法是正确的,不用改这部分逻辑,只要确保集合本身是每个员工独有的就行。
内容的提问来源于stack exchange,提问作者Aswin S Kumar
相关产品推荐
相关产品推荐

