我有这段代码,我希望使用保留函数从正在运行的作业的可变 HashSet 中删除具有给定 job_id 的返回作业,但是不会删除预期的条目。我在下面有一些调试代码及其输出(远低于),它遍历集合以显示集合中有一个元素等于测试元素,但是当使用保留函数时集合大小不会改变保留不等于该作业 ID 的元素。
if(action=="request_this") {
println("RS >%d<\n".format(job.job_id))
for(j <- jobs_running) println(">%d< ".format(j.job_id) + (if(j.job_id==job.job_id) "true" else "false"))
}
val c1 = jobs_running.size
jobs_running.retain(x => x.job_id!=job.job_id)
println(action+" NET CHANGE %d".format(jobs_running.size-c1))
输出:
RS >1259<
>1055< false
>1019< false
>1051< false
>1083< false
>1015< false
>1215< false
>1127< false
>1259< true
>1107< false
>1047< false
>1035< false
request_this NET CHANGE 0
让我更加困惑的是,调试代码中引用的“action”var 只是与返回作业对象中的 action_id 等效的纯文本。我只能针对一种作业操作类型“request_this”来重现此问题。如果它是不同的类型,那么我会得到预期的输出:
request_that NET CHANGE -1
更新——普遍的共识似乎与哈希码有关。我修改了调试代码以打印出 Job 对象和 job_id 值的哈希码。
if(action=="request_screenshot") {
println(">>%d< ".format(job.job_id) + job.hashCode + " " + job.job_id.hashCode+"\n")
for(j <- jobs_running) println(">%d< ".format(j.job_id) + j.hashCode + " " + j.job_id.hashCode)
}
我得到的输出看起来像测试作业(第一行)的哈希码和集合中的作业匹配 job_id 值和整个作业对象(我在匹配的集合元素打印输出旁边放了一个 *):
>>1267< 1619488678 1267
>1015< 2124747326 1015
>1043< -183172091 1043
>1107< -353858330 1107
>1123< -1258875190 1123
>963< 1958632623 963
>1039< 226958301 1039
>1023< 148063445 1023
>1215< -972672885 1215
>959< 283572883 959
>971< -2080242470 971
>1091< -1549619606 1091
>1019< -529588663 1019
>1047< -552719093 1047
>967< 626939580 967
>1035< 1782547037 1035
>1263< -874427822 1263
>1027< -228877131 1027
>1031< 441847990 1031
*>1267< 1619488678 1267
>1211< -1435736028 1211
>1191< 48617136 1191
>1119< -1737229053 1119
>1011< 1056625401 1011
>1127< -1547902819 1127
>1251< -358437524 1251
UPDATE2——我最终重写了我的代码,以便 Job 对象是完全不可变的,并且症状似乎已经解决了,尽管我仍然希望我了解到底发生了什么。关于 hashcode/equals implimentations 是罪魁祸首,值得一提的是 Job 类是使用“case class”定义的。