Scala 意外的HashSet.retain行为
我有一段代码,其中我希望使用retain函数从运行作业的可变HashSet中删除具有给定job_id的返回作业,但是没有删除预期的条目。我在下面有一些调试代码及其输出(远在下面),它在集合中迭代,以显示集合中有一个元素等于测试元素,但当使用retain函数仅保留不等于该作业id的元素时,集合大小不会改变Scala 意外的HashSet.retain行为,scala,Scala,我有一段代码,其中我希望使用retain函数从运行作业的可变HashSet中删除具有给定job_id的返回作业,但是没有删除预期的条目。我在下面有一些调试代码及其输出(远在下面),它在集合中迭代,以显示集合中有一个元素等于测试元素,但当使用retain函数仅保留不等于该作业id的元素时,集合大小不会改变 if(action=="request_this") { println("RS >%d<\n".format(job.job_id)) for(j <- jo
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))
更新——普遍的共识似乎与哈希代码有关。我修改了调试代码,以打印作业对象和作业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)
}
if(操作==“请求屏幕截图”){
println(“>>>%d<”.format(job.job\u id)+job.hashCode+“”+job.job\u id.hashCode+“\n”)
对于(j>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——我最终重写了我的代码,这样作业对象就完全不可变了,症状似乎已经自行解决了,尽管我仍然希望能够理解到底发生了什么。关于hashcode/equals实现是罪魁祸首,可能值得一提的是,作业类是使用“案例课”两个问题:
hashCode
的实现是否遵循?也许您可以提供它们的实现hashCode
使用的字段是不可变的,还是插入到集合中后未发生变异HashSet
,而不是SortedSet
,对吗?在SortedSet
上,您还需要担心排序的实现
集合元素的
equals
和hashCode
的中断实现可能会导致类似的情况。我只是想问:“设置以显示集合中有一个元素等于测试元素”等于“它看起来像另一个”或“obj1.equals(obj2)”"?equals
方法也是,不是吗?@pedrofurla显示的输出表明equals
对于某些元素返回true,因此即使它不是一个好的实现,它也应该删除一些内容。job_id值是不可变的Int,但是整个job对象中的其他值是可变的。我认为我可以这样看待它nt数据类型不是ref,而job_id是唯一被比较的值,因此任何hashCode都应该返回一个匹配项。这是正确的,还是我误解了什么?@DanCollins没有查看hashCode
代码,我无法确定,但问题是:如果hashCode
的值在放置它的时间之间发生变化在设置和调用retain
时,代码将无法找到该元素!它将基于当前的hashCode
查看一个bucket,但它是基于原始的hashCode
存储在一个bucket中的。明白了——这对我来说很有意义。谢谢!
request_that NET CHANGE -1
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)
}
>>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