我对哈希码知之甚少。我发现这个代码可以打印出碰撞。
您能告诉我碰撞是什么以及如何减少碰撞吗? 我们为什么要使用哈希码?
public static int getHash(String str, int limit)
{
int hashCode = Math.abs(str.hashCode()%(limit));
return hashCode;
}
/**
* @param args
*/
public static void main(String[] args)
{
int hashLimit = 10000;
int stringsLimit = 10000;
String[] arr = new String[hashLimit];
List<String> test = new ArrayList<String>();
Random r = new Random(2);
for ( int i = 0 ; i < stringsLimit ; i++ )
{
StringBuffer buf = new StringBuffer("");
for ( int j = 0 ; j < 10 ; j++ )
{
char c = (char)(35+60*r.nextDouble());
buf.append(c);
}
test.add(buf.toString());
//System.out.println(buf.toString());
}
int collisions = 0;
for ( String curStr : test )
{
int hashCode = getHash(curStr,hashLimit);
if ( arr[hashCode] != null && !arr[hashCode].equals(curStr) )
{
System.out.println("collision of ["+arr[hashCode]+"] ("+arr[hashCode].hashCode()+" = "+hashCode+") with ["+curStr+"] ("+curStr.hashCode()+" = "+hashCode+")");
collisions++;
}
else
{
arr[hashCode] = curStr;
}
}
System.out.println("Collisions: "+collisions);
}
答案 0 :(得分:18)
你能告诉我什么是碰撞以及如何减少它?
当两个不相等的对象具有相同的哈希码时发生冲突。他们是生活中的事实 - 你需要处理它。
我们为什么要使用哈希码?
因为它们可以快速按键查找值,基本上。哈希表可以使用哈希代码非常快速地将可能的密钥匹配集合下载到非常小的集合(通常只有一个),此时您需要检查 actual < / em>密钥相等。
你应该从不假设两个哈希码相等意味着它们的派生对象是相等的。只有相反的情况:假设一个正确的实现,如果两个对象提供不同的哈希码,那么它们不相等。
答案 1 :(得分:2)
回答问题的其他部分:为了减少冲突的可能性,您应该实现一个散列算法,该算法在可能的输入集上提供均匀的散列码分布。
例如,假设您为哈希hashCode()
实例实施了一个天真的MyString
方法:
public class MyString {
private final char[] arr;
// Constructor and other methods.
public int hashCode() {
return arr.length == 0 ? 0 : (int) arr[0];
}
}
在此示例中,仅使用第一个字符来创建哈希码。因此,如果你要哈希字符串:“apple”,“anaconda”,“轶事”,它们都会产生相同的哈希值。更有效的哈希代码将检查字符数组中的所有字母以确定哈希码值,这有望减少冲突的可能性。
答案 2 :(得分:0)
如果两个不同的 不相等的对象具有相同的哈希码,则会发生“冲突”。这个可能是一个问题,例如当尝试将两个对象用作Hashmap中的键时。