我有一些使用标准Java集合的代码:arrays,ArrayDeques,HashMaps,Lists,HashSets.我的代码应该是确定性的:所有元素的哈希码,集合的初始内容等预计仅取决于输入数据.代码的最终输出是从keySet()一些HashMap生成的.
我注意到生成的keySet中元素的顺序有时会在运行之间发生变化.这是什么意思?
这与Windows 7 x64上的JDK 1.7.0_60,x86完全一致.据称,JDK 1.8.0_05不会发生这种情况(或很少发生).此外,在上述JDK之间切换时,生成的keySet中的元素顺序(以及处理数据项的整体顺序)也会发生变化.
我怀疑,这是HashSet的一些功能,但无法将其跟踪到特定的代码行.
UPD 1我真的不需要确定性集合,我知道HashSet不提供保证.我只是想找到非确定性行为的原因.如果它在库代码中 - 很好.但如果它在我的代码中 - 我可能不得不修复它.因此问题.
UPD 2当然,我在发布问题后立即找到答案.就在1.7的HashMap.java的开头:
/**
* A randomizing value associated with this instance that is applied to
* hash code of keys to make hash collisions harder to find. If 0 then
* alternative hashing is disabled.
*/
transient int hashSeed = 0;
Run Code Online (Sandbox Code Playgroud)
在1.8中,这种随机化似乎不再存在.
我正在使用 Visual Studio 2017 以标准 C++ 开发控制台应用程序。安装VS2017时,我可以同时安装Win 8.1 SDK和Win 10 SDK。VS2017 似乎默认提供 Win 10 SDK,但我经常遇到配置为使用 Win 8.1 SDK 的项目(例如,MPIR或在以前版本的 VS 中创建的项目)。因此,我想知道:
假设我有许多模块,它们都使用一种模块类型进行参数化,并且彼此之间也具有依赖关系:
module type AT = sig
end
module B(A: AT) = struct
module Hash = struct
type t = int
let equal b1 b2 = b1 = b2
let hash b = b
end
end
module C(A: AT) = struct
module B = B(A)
module Hashtbl = Hashtbl.Make(B.Hash)
let make () = Hashtbl.create 16
end
module D(A: AT) = struct
module B = B(A)
module Hashtbl = Hashtbl.Make(B.Hash)
let use ht =
Hashtbl.clear ht
end
module E(A: AT) = struct …Run Code Online (Sandbox Code Playgroud) 我无法理解OCaml中模块的相等性.函数应该是应用程序(这是互联网所声称的),但这似乎有时会失败,我不能完全看到它背后的一般规则.
这是我的示例代码:
module type PT = sig end
module P = struct end
let () =
Random.self_init ()
module OrigHashtbl = Hashtbl
module Hashtbl = struct
module Make(Hash: OrigHashtbl.HashedType) = struct
let random = Random.int 1000000
type 'a t = { t_list: (Hash.t * 'a) list }
let create _ =
Format.printf "Random %d@." random;
{ t_list = [] }
let mem ht v =
Format.printf "Random %d@." random;
List.mem_assoc v ht.t_list
end
end
module Hash = struct
type t …Run Code Online (Sandbox Code Playgroud)