/** * Returns a power of two size for the given target capacity. */ static final int tableSizeFor(int cap) { int n = cap - 1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; }
public class Main { static final int MAXIMUM_CAPACITY = 1 << 30; static int tableSizeFor(int cap) { int n = cap - 1; System.out.println("\nn = cap - 1"); System.out.println(fillToLength(Integer.toBinaryString(n))); System.out.println("\nn |= n >>> 1"); print(n, n >>> 1); n |= n >>> 1; System.out.println(fillToLength(Integer.toBinaryString(n))); System.out.println("\nn |= n >>> 2"); print(n, n >>> 2); n |= n >>> 2; System.out.println(fillToLength(Integer.toBinaryString(n))); System.out.println("\nn |= n >>> 4"); print(n, n >>> 4); n |= n >>> 4; System.out.println(fillToLength(Integer.toBinaryString(n))); System.out.println("\nn |= n >>> 8"); print(n, n >>> 8); n |= n >>> 8; System.out.println(fillToLength(Integer.toBinaryString(n))); System.out.println("\nn |= n >>> 16"); print(n, n >>> 16); n |= n >>> 16; System.out.println(fillToLength(Integer.toBinaryString(n))); System.out.println("\nn + 1"); System.out.println(fillToLength(Integer.toBinaryString(n + 1))); return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; }
private static void print(int a, int b) { System.out.println(fillToLength(Integer.toBinaryString(a)) + " |\n" + fillToLength(Integer.toBinaryString(b)) + " ="); }
private static String fillToLength(String source) { if (source.length() < 32) { StringBuilder builder = new StringBuilder(source); while (builder.length() < 32) { builder.insert(0, '0'); } return builder.toString(); } return source; }
public static void main(String[] args) { String source = "1000000000000110000000011000000"; int cap = Integer.parseInt(source, 2); System.out.println("cap: " + cap); System.out.println("cap bin: \n" + fillToLength(source)); int size = tableSizeFor(cap); System.out.println("result: " + size); } }
/** * Computes key.hashCode() and spreads (XORs) higher bits of hash * to lower. Because the table uses power-of-two masking, sets of * hashes that vary only in bits above the current mask will * always collide. (Among known examples are sets of Float keys * holding consecutive whole numbers in small tables.) So we * apply a transform that spreads the impact of higher bits * downward. There is a tradeoff between speed, utility, and * quality of bit-spreading. Because many common sets of hashes * are already reasonably distributed (so don't benefit from * spreading), and because we use trees to handle large sets of * collisions in bins, we just XOR some shifted bits in the * cheapest possible way to reduce systematic lossage, as well as * to incorporate impact of the highest bits that would otherwise * never be used in index calculations because of table bounds. */ static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }