1

このコード スニペットでは、特定の job_id を持つ返されたジョブが、retain 関数を使用して実行中のジョブの変更可能な HashSet から削除されることを期待していますが、予想されるエントリは削除されていません。以下にいくつかのデバッグ コードとその出力 (はるか下) を示します。これはセットを反復処理して、セット内にテスト要素と等しい要素があることを示しますが、retain 関数のみが使用されている場合はセット サイズは変更されません。そのジョブ 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_id に相当するプレーンテキストにすぎないことです。この問題を再現できるのは、1 つのジョブ アクション タイプ「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 実装に関しては、Job クラスが「ケース クラス」を使用して定義されたことに言及する価値があるかもしれません。

4

1 に答える 1

2

2 つの質問:

  1. の実装は要件hashCodeに従っていますか? おそらく、それらの実装を提供できます。

  2. フィールドはhashCode不変で使用されていますか、それともセットに挿入された後に変更されていませんか?

編集

3 番目の質問:

  1. これはHashSetではなくSortedSetですよね?では、実装SortedSetについても心配する必要があります。Ordering
于 2013-10-19T00:26:18.127 に答える