我有这个测试代码:
import java.util.*;
class MapEQ {
public static void main(String[] args) {
Map<ToDos, String> m = new HashMap<ToDos, String>();
ToDos t1 = new ToDos("Monday");
ToDos t2 = new ToDos("Monday");
ToDos t3 = new ToDos("Tuesday");
m.put(t1, "doLaundry");
m.put(t2, "payBills");
m.put(t3, "cleanAttic");
System.out.println(m.size());
} }
class ToDos{
String day;
ToDos(String d) { day = d; }
public boolean equals(Object o) {
return ((ToDos)o).day == this.day;
}
// public int hashCode() { return 9; }
}
Run Code Online (Sandbox Code Playgroud)
何时// public int hashCode() { return …
是否可以使用java的哈希码函数为不同的字符串使用相同的哈希码?或者如果可能的话,它的可能性百分比是多少?
如何做Object.hashCode()和System.identityHashCode()工作在后端?是否identityHashCode()返回对象的引用?是否hashCode()取决于?对象?==运算符如何在后端工作.
hashCode()和之间有什么区别identityHashCode()?
浏览string.GetHashCode使用Reflector的源代码会显示以下内容(对于mscorlib.dll版本4.0):
public override unsafe int GetHashCode()
{
fixed (char* str = ((char*) this))
{
char* chPtr = str;
int num = 0x15051505;
int num2 = num;
int* numPtr = (int*) chPtr;
for (int i = this.Length; i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1]; …Run Code Online (Sandbox Code Playgroud) 问题的标题说明了一切.我一直在研究SHA-1和大多数地方,我看到它是40个十六进制字符长,对我来说是640bit.它只能用10个十六进制字符160bit = 20byte来表示.一个十六进制字符可以表示2个字节对吗?为什么它需要的时间是它的两倍?我的理解中缺少什么.
如果使用Base32或Base36,SHA-1甚至不能只有5个或更少的字符?
考虑以下代码:
Console.WriteLine("Hello, World!".GetHashCode());
Run Code Online (Sandbox Code Playgroud)
第一次运行:
139068974
第二次运行:
-263623806
现在考虑用 Kotlin 编写的相同内容:
println("Hello, World!".hashCode())
Run Code Online (Sandbox Code Playgroud)
第一次运行:
1498789909
第二次运行:
1498789909
为什么string.NET 中的每次执行的哈希码都会发生变化,但在其他运行时(如 JVM)上却不会发生变化?
背景:
我们希望能够在查询中快速匹配这些字符串,而不会影响大量连接.
所以我想在主表中存储所有这些字符串的哈希码并将其包含在索引中,因此只有当哈希码匹配时才会由数据库处理连接.
那么我如何获得一个好的哈希码呢?我可以:
那人们怎么想?
最后,我只是连接字符串并计算连接的哈希码,因为它很简单并且工作得很好.
(如果你关心我们使用的是.NET和SqlServer)
Bug!,Bug!
引自 Eric Lippert的GetHashCode指南和规则
System.String.GetHashCode的文档特别指出,两个相同的字符串在CLR的不同版本中可以具有不同的哈希码,实际上它们也是如此.不要在数据库中存储字符串哈希并期望它们永远是相同的,因为它们不会.
所以不应该使用String.GetHashcode().
方法##和有hashCode什么区别?
无论hashCode我使用哪个类或重载,它们似乎都输出相同的值.谷歌也没有帮助,因为它找不到符号##.
我们可以发现hashcode的list是本身含有的element?
我知道这是一个不好的做法,但这是面试官问的。
当我运行以下代码时,它会抛出一个StackOverflowError:
public class Main {
public static void main(String args[]) {
ArrayList<ArrayList> a = new ArrayList();
a.add(a);
a.hashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我有两个问题:
StackOverflowError?通常,Java会根据给定调用端遇到的实现数量来优化虚拟调用.当你看一下,这可以很容易地在我的基准测试结果中看到,这是一个返回存储的简单方法.这是微不足道的myCodeint
static abstract class Base {
abstract int myCode();
}
Run Code Online (Sandbox Code Playgroud)
与几个完全相同的实现
static class A extends Base {
@Override int myCode() {
return n;
}
@Override public int hashCode() {
return n;
}
private final int n = nextInt();
}
Run Code Online (Sandbox Code Playgroud)
随着实现数量的增加,方法调用的时序从两个实现的0.4 ns增加到1.2 ns,再增长到11.6 ns,然后缓慢增长.当JVM看到多个实现时,preload=true即时序略有不同(因为instanceof需要进行测试).
到目前为止,一切都很清楚,但hashCode行为却相当不同.特别是,在三种情况下,它慢了8-10倍.知道为什么吗?
我很好奇,如果hashCode可以通过手动调度来帮助穷人,那可能会很多.

几个分支完美地完成了这项工作:
if (o instanceof A) {
result += ((A) o).hashCode();
} else if (o instanceof B) {
result += ((B) o).hashCode(); …Run Code Online (Sandbox Code Playgroud)