RegularImmutableBiMap(Map.Entry<?, ?>[] entriesToAdd) { int n = entriesToAdd.length; int tableSize = Hashing.closedTableSize(n, 1.2D); this.mask = (tableSize - 1); ImmutableMapEntry<K, V>[] keyTable = createEntryArray(tableSize); ImmutableMapEntry<K, V>[] valueTable = createEntryArray(tableSize); ImmutableMapEntry<K, V>[] entries = createEntryArray(n); int hashCode = 0; for (int i = 0; i < n; i++) { Map.Entry<K, V> entry = entriesToAdd[i]; K key = entry.getKey(); V value = entry.getValue(); CollectPreconditions.checkEntryNotNull(key, value); int keyHash = key.hashCode(); int valueHash = value.hashCode(); int keyBucket = Hashing.smear(keyHash) & this.mask; int valueBucket = Hashing.smear(valueHash) & this.mask; ImmutableMapEntry<K, V> nextInKeyBucket = keyTable[keyBucket]; for (ImmutableMapEntry<K, V> keyEntry = nextInKeyBucket; keyEntry != null; keyEntry = keyEntry.getNextInKeyBucket()) { checkNoConflict(!key.equals(keyEntry.getKey()), "key", entry, keyEntry); } ImmutableMapEntry<K, V> nextInValueBucket = valueTable[valueBucket]; for (ImmutableMapEntry<K, V> valueEntry = nextInValueBucket; valueEntry != null; valueEntry = valueEntry.getNextInValueBucket()) { checkNoConflict(!value.equals(valueEntry.getValue()), "value", entry, valueEntry); } ImmutableMapEntry<K, V> newEntry = (nextInKeyBucket == null) && (nextInValueBucket == null) ? new ImmutableMapEntry.TerminalEntry(key, value) : new NonTerminalBiMapEntry(key, value, nextInKeyBucket, nextInValueBucket); keyTable[keyBucket] = newEntry; valueTable[valueBucket] = newEntry; entries[i] = newEntry; hashCode += (keyHash ^ valueHash); } this.keyTable = keyTable; this.valueTable = valueTable; this.entries = entries; this.hashCode = hashCode; }
static StringBuilder newStringBuilderForCollection(int i) { CollectPreconditions.checkNonnegative(i, "size"); return new StringBuilder((int) Math.min((long) i << 3, 0x40000000L)); }