最近出现了一个有趣的问题.我们遇到了一些hashCode()用作MD5加密的salt源的代码,但是这引出了一个问题:将hashCode()在不同的VM,不同的JDK版本和操作系统上为同一对象返回相同的值吗?即使它没有保证,它现在在任何时候都有变化吗?
编辑:我的意思是,String.hashCode()而不是更一般Object.hashCode(),当然可以被覆盖.
我有一个坐标为键的HashMap.
坐标有3个长度,保持x,y和z坐标.(坐标是并且需要是一个自定义类,坐标需要很长).
现在我希望能够通过以下方式访问例如字段[5,10,4] : hashMap.get(new Coordinate(5, 10, 4)).
我已经实现了equals方法,但这还不够,因为显然我还需要为hashCode提供一个实现.所以我的问题是我如何从三个长度生成一个独特的hashCode?.
附加:使用外部库中的哈希生成器不是选项.
我知道,当覆盖hashcode()和equals()我的持久化实体的我不应该包括ID,只包括有意义的属性唯一标识对象.但是Hibernate version用于乐观并发控制的字段呢?我应该跳过它,就像ID一样吗?如果让我们说new User(name='John', version=1).equals(new User(name='John',version=2)),不管怎么说它不会混淆Hibernate OCC呢?
hibernate version hashcode optimistic-locking optimistic-concurrency
如果只有一个对象的某些字段代表实际状态,我认为在覆盖equals和hashCode... 时可以忽略这些字段.
我对此感到不安,并想问,
equals/中的某些字段时是否有任何文档或指南hashCode?在我的特殊情况下,我正在探索一个问题的状态空间.我想保留一组访问状态,但我也在考虑包括通往该州的路径.显然,两个国家是平等的,即使它们是通过不同的途径找到的.
我也问过类似的问题为string.GetHashCode()在.NET方法.从那时起,我了解到如果我们要在不同的机器上使用它,我们就不能依赖于buit-in类型的哈希代码的隐式实现.因此,我假设Java实现String.hashCode()在不同的硬件配置中也不稳定,并且可能在VM之间表现不同(不要忘记不同的VM实现)
目前,我们正在讨论一种通过散列将字符串安全地转换为Java中的数字的方法,但是散列算法必须在群集的不同节点之间保持稳定,并且要快速评估,因为使用频率很高.我的队友坚持使用原生hashCode方法,我需要一些合理的论据让他们重新考虑另一种方法.目前,我能想到的唯一的机器配置之间(x86和x64)的JVM可能不同的厂商对某些机器(几乎适用于我们的情况下)和字节顺序不同的差异,根据不同的算法是在机器上跑.当然,也可以考虑字符编码.
虽然所有这些事情都浮现在我脑海中,但我并不是百分之百肯定他们中的任何一个都有足够的理由,我很感激你在这方面的专业知识和经验.这将有助于我建立更强大的论据,以支持编写自定义哈希算法.另外,我很欣赏有关实施时不应该做的建议.
我对使用EqualsVerifier库的Java 有一些疑问equals和hashCode合同.
想象一下,我们有类似的东西
public abstract class Person {
protected String name;
@Override
public boolean equals(Object obj) {
// only name is taken into account
}
@Override
public int hashCode() {
// only name is taken into account
}
}
Run Code Online (Sandbox Code Playgroud)
以下扩展课程:
public final class Worker extends Person {
private String workDescription;
@Override
public final boolean equals(Object obj) {
// name and workDescription are taken into account
}
@Override
public final int hashCode() {
// name …Run Code Online (Sandbox Code Playgroud) 假设我有一个类,其中所有实例都被认为是相等的.典型的用例是针对没有任何状态但只表现为函数的类.
public class ToStringFunction implements Function<Object, String> {
@Override
public String apply(Object o) {
return o.toString();
}
@Override
public boolean equals(Object o) {
return o instanceof ToStringFunction;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,应该如何实现hashCode方法?当然,为了遵守equals/hashCode合约,它需要是一个常量值.但那应该是什么价值?如果使用诸如0或1之类的某些微不足道的值,则可能导致与其他类似类的冲突.
所以这似乎归结为这个问题:如何实现一个对于给定类可能是唯一的hashCode,但对于它的所有实例都是相同的.
我想出了这两个想法.你觉得怎么样,他们是否理智?
@Override
public int hashCode() {
return ToStringFunction.class.hashCode();
}
@Override
public int hashCode() {
return "ToStringFunction".hashCode();
}
Run Code Online (Sandbox Code Playgroud) 我有一个由两个字符串和一个枚举组成的类.我正在尝试将此类的实例用作字典中的键.不幸的是,我似乎没有正确实现IEquatable.这是我如何做到的:
public enum CoinSide
{
Heads,
Tails
}
public class CoinDetails : IComparable, IEquatable<CoinDetails>
{
private string denomination;
private string design;
private CoinSide side;
//...
public int GetHashCode(CoinDetails obj)
{
return string.Concat(obj.Denomination, obj.Design, obj.Side.ToString()).GetHashCode();
}
public bool Equals(CoinDetails other)
{
return (this.Denomination == other.Denomination && this.Design == other.Design && this.Side == other.Side);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我似乎仍然无法在我的字典中查找项目.此外,以下测试失败:
[TestMethod]
public void CoinDetailsHashCode()
{
CoinDetails a = new CoinDetails("1POUND", "1997", CoinSide.Heads);
CoinDetails b = new CoinDetails("1POUND", "1997", CoinSide.Heads);
Assert.AreEqual(a.GetHashCode(), b.GetHashCode());
}
[TestMethod]
public void …Run Code Online (Sandbox Code Playgroud) 我正在尝试用C++实现一个类,我希望每个类都有自己的hashcode实现(基本上将它用作unordered_map&中的键unordered_set)
例如:
class CustomClass{
int a;
vector<int> b;
string c;
bool operator ==(const CustomClass& o) const{
return ((a == o.a) && (b == o.b) && (c == o.c));
}
/*
Is it possible to define the hashcode function here instead of defining it outside the class.
size_t operator()() const {
// Some custom logic for calculating hash of CustomClass using
// the hash Values of its individual fields
std::size_t h = 0;
for(int& t : b){ …Run Code Online (Sandbox Code Playgroud) 以前我问了一个关于组合SHA1 + MD5 的问题,但之后我理解计算SHA1然后延迟文件的MD5并不比SHA256快.在我的情况下,4.6 GB文件大约需要10分钟,在Linux系统中使用默认实现SHA256和(C#MONO).
public static string GetChecksum(string file)
{
using (FileStream stream = File.OpenRead(file))
{
var sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(stream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我读了这个主题,并以某种方式根据他们所说的改变我的代码:
public static string GetChecksumBuffered(Stream stream)
{
using (var bufferedStream = new BufferedStream(stream, 1024 * 32))
{
var sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(bufferedStream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
但它没有这样的感情,需要大约9分钟.
然后我尝试通过sha256sumLinux中的命令测试我的文件中的相同文件,它需要大约28秒,上面的代码和Linux命令都给出相同的结果!
有人建议我阅读Hash Code和Checksum之间的区别,然后我会谈到这个解释差异的主题.
我的问题是:
是什么导致上述代码和Linux之间的这种不同sha256sum? …