import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.Random;
import java.util.List;
/**
* @description:
* @author: wukong
* @remark: create wukong 2019/12/26 22:49
*/
public class HashTest {
public static void main(String[] args) {
int length = 1 << 8;
List<Double> doubles = new ArrayList<>(100);
List<Double> double2s = new ArrayList<>(100);
// 测试次数
int count = 100;
for (int i = 0; i < count; i++) {
hashCalculate(length, doubles, double2s);
}
System.out.println("均值1:" + doubles.stream().mapToDouble((item) -> item).summaryStatistics().getAverage());
System.out.println("均值2:" + double2s.stream().mapToDouble((item) -> item).summaryStatistics().getAverage());
System.out.println("集合1:" + JSON.toJSON(doubles));
System.out.println("集合2" + JSON.toJSON(double2s));
}
/**
* @Description: hash碰撞率计算
*/
private static void hashCalculate(int length, List<Double> doubles, List<Double> double2s) {
int cardinal = length - 1;
int load = (int) (length * 0.75);
int crash = 0;
int crash2 = 0;
List<Integer> list = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
for (int i = 0; i < load; i++) {
// 随机key获取哈希值
int hash = getRandomString().hashCode();
// 直接与基数进行与运算
int result = cardinal & hash;
// jdk8中hashmap扰动函数
int disturbHash = hash ^ (hash >>> 16);
// 扰动后的值与运算
int result2 = cardinal & disturbHash;
//统计直接运算碰撞次数
if (!list.contains(result)) {
list.add(result);
} else {
crash++;
}
//统计扰乱后碰撞次数
if (!list2.contains(result2)) {
list2.add(result2);
} else {
crash2++;
}
}
double crashProbability = crash / (double) length;
double crashProbability2 = crash2 / (double) length;
doubles.add(crashProbability);
double2s.add(crashProbability2);
// System.out.println("当长度为" + length + "时,hash值直接与运算的碰撞率为:" + crashProbability);
// System.out.println("当长度为" + length + "时,扰动函数之后与运算的碰撞率为:" + crashProbability2);
}
/**
* @Description: 获取随机key字符串
*/
private static String getRandomString() {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
int length = 8;
for (int i = 0; i < length; i++) {
int number = random.nextInt(62);
sb.append(str.charAt(number));
}
return sb.toString();
}
}