HashCode有多大可能重复?
2007-01-05 15:59
176 查看
今天有同事提议用String的hashcode得到int类型作为主键。其实hashcode重复的可能性超大,下面是java的缺省算法:
public int hashCode()
{
int h = hash;
if (h == 0)
{
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++)
{
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
但是什么情况下会重复?下面是测试代码
import java.util.HashMap;
public class Test
{
static HashMap map = new HashMap();
private static char startChar = 'A';
private static char endChar = 'z';
private static int offset = endChar - startChar + 1;
private static int dup = 0;
public static void main(String[] args)
{
int len = 3;
char[] chars = new char[len];
tryBit(chars, len);
System.out.println((int)Math.pow(offset, len) + ":" + dup);
}
private static void tryBit(char[] chars, int i)
{
for (char j = startChar; j <= endChar; j++)
{
chars[i - 1] = j;
if (i > 1)
tryBit(chars, i - 1);
else
test(chars);
}
}
private static void test(char[] chars)
{
String str = new String(chars).replaceAll("[^a-zA-Z_]", "").toUpperCase();// 195112:0
//String str = new String(chars).toLowerCase();//195112:6612
//String str = new String(chars).replaceAll("[^a-zA-Z_]","");//195112:122500
//String str = new String(chars);//195112:138510
int hash = str.hashCode();
if (map.containsKey(hash))
{
String s = (String) map.get(hash);
if (!s.equals(str))
{
dup++;
System.out.println(s + ":" + str);
}
} else
{
map.put(hash, str);
// System.out.println(str);
}
}
}
在A-z范围内有特殊字符,从结果看,仅仅3位长度的字符串:
不处理: 138510次重复
去掉字母意外字符: 122500次重复
所有字符转小写:6612次重复(少了很多)
去掉字母意外字符,并且转小写:没有重复!4位字符串也没见重复
不难看出:
1. 缺省实现为英文字母优化
2. 字母大小写可能导致重复
可能:
长字符串可能hashcode重复
中文字符串和特殊字符可能hashcode重复
public int hashCode()
{
int h = hash;
if (h == 0)
{
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++)
{
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
但是什么情况下会重复?下面是测试代码
import java.util.HashMap;
public class Test
{
static HashMap map = new HashMap();
private static char startChar = 'A';
private static char endChar = 'z';
private static int offset = endChar - startChar + 1;
private static int dup = 0;
public static void main(String[] args)
{
int len = 3;
char[] chars = new char[len];
tryBit(chars, len);
System.out.println((int)Math.pow(offset, len) + ":" + dup);
}
private static void tryBit(char[] chars, int i)
{
for (char j = startChar; j <= endChar; j++)
{
chars[i - 1] = j;
if (i > 1)
tryBit(chars, i - 1);
else
test(chars);
}
}
private static void test(char[] chars)
{
String str = new String(chars).replaceAll("[^a-zA-Z_]", "").toUpperCase();// 195112:0
//String str = new String(chars).toLowerCase();//195112:6612
//String str = new String(chars).replaceAll("[^a-zA-Z_]","");//195112:122500
//String str = new String(chars);//195112:138510
int hash = str.hashCode();
if (map.containsKey(hash))
{
String s = (String) map.get(hash);
if (!s.equals(str))
{
dup++;
System.out.println(s + ":" + str);
}
} else
{
map.put(hash, str);
// System.out.println(str);
}
}
}
在A-z范围内有特殊字符,从结果看,仅仅3位长度的字符串:
不处理: 138510次重复
去掉字母意外字符: 122500次重复
所有字符转小写:6612次重复(少了很多)
去掉字母意外字符,并且转小写:没有重复!4位字符串也没见重复
不难看出:
1. 缺省实现为英文字母优化
2. 字母大小写可能导致重复
可能:
长字符串可能hashcode重复
中文字符串和特殊字符可能hashcode重复
相关文章推荐
- HashCode有多大可能重复?
- HashCode有多大可能重复?
- HashCode有多大可能重复?
- 12、一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。 请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
- oracle按时间排序,取得表中第一条数据(数据可能重复)
- 找出一个字符数组(元素不重复)所有可能字符的组合
- 单片机寄存器组注意重复使用原数据可能被覆盖危险(C51编程也注意)
- Python开发中有可能遇到的套接字重复使用错误
- 宏定义重复可能出现的情况
- 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
- 你可能不清楚的Java细节(1)--为什么Boolean的hashCode()方法返回值是1231或1237
- Search for a range, 在一个可能有重复元素的有序序列里找到指定元素的起始和结束位置
- 请给Array本地对象增加一个原型方法,它的用途是删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除的重复条目的新数组。
- 求1-n之间所有不重复的可能的值的和等于m的组合
- 删除数组条目中重复的条目(可能有多个),返回值是一个仅包含被删除的重复条目的新数组。
- 15、一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。
- 蓝桥杯 取字母组成串 * A B C D中取5次,每个字母都可以重复取出,形成一个串。 现在要求,串中A出现的次数必须为偶数(0次也算偶数)。 求可以形成多少种可能的串。
- hashcode重复可能性探究
- 给Array本地对象增加一个原型方法,用于删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除重复条目的新数组
- 转载 .net面试题大全(有答案) & asp.net面试集合 [可能有部分重复]