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(); } }