HashBiMap
AbstractMap类实现了Map接口定义的一些方法,而BiMap类定义了其子类需要实现的一些方法,使得所有实现BiMap的类必须符合其独有的特性:键、值都是唯一的。HashBiMap类中主要有以下几个成员变量:
HashBiMap类中主要有一下几个成员变量:
1 private static final double LOAD_FACTOR = 1.0; 2 private transient BiEntry<K, V>[] hashTableKToV; 3 private transient BiEntry<K, V>[] hashTableVToK; 4 private transient int size; 5 private transient int mask; 6 private transient int modCount;
LOAD_FACTOR是承载因子,这里等于1,而我们熟悉的HashMap承载因子为0.75。LOAD_FACTOR关系到当容器中元素的个数达到了总容量的多少就得分配新的空间。hashTableKToV和hashTableVToK分别存储类型为BiEntry的键值对,都是存储键->值对的,但是目的不一样。size是HashBiMap中元素的个数;mask在求元素的hash值有用。
HashBiMap类提供了以下三个静态函数来构造一个HashBiMap,并将构造函数设为private,使外部通过HashBiMap.create(.....)的方式创建容器对象
1 public static <K, V> HashBiMap<K, V> create() { 2 return create(16); 3 } 4 public static <K, V> HashBiMap<K, V> create(int expectedSize) { 5 return new HashBiMap<K, V>(expectedSize); 6 } 7 public static <K, V> HashBiMap<K, V> create(Map<? extends K, ? extends V> map) { 8 HashBiMap<K, V> bimap = create(map.size()); 9 bimap.putAll(map); 10 return bimap; 11 } 12 13 private HashBiMap(int expectedSize) { 14 init(expectedSize); 15 }
可见,HashBiMap的默认容量为16,当用户自己决定容器大小(expectedSize)的时候,它是以下方法来分配容量的。
private HashBiMap(int expectedSize) { init(expectedSize); } private void init(int expectedSize) { checkArgument(expectedSize >= 0, "expectedSize must be >= 0 but was %s", expectedSize); int tableSize = Hashing.closedTableSize(expectedSize, LOAD_FACTOR); this.hashTableKToV = createTable(tableSize); this.hashTableVToK = createTable(tableSize); this.mask = tableSize - 1; this.modCount = 0; this.size = 0; } static int closedTableSize(int expectedEntries, double loadFactor) { // Get the recommended table size. // Round down to the nearest power of 2. expectedEntries = Math.max(expectedEntries, 2); int tableSize = Integer.highestOneBit(expectedEntries); // Check to make sure that we will not exceed the maximum load factor. if (expectedEntries > (int) (loadFactor * tableSize)) { tableSize <<= 1; return (tableSize > 0) ? tableSize : MAX_TABLE_SIZE; } return tableSize; } public static int highestOneBit(int i) { // HD, Figure 3-1 i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1); }
从内部实现,HashBiMap是利用hashTableKToV和hashTableVToK数组作为hash映射的,利用key求得的Hash值是映 射到hashTableKToV数组中的,而利用value求得的Hash值是映射到hashTableVToK数组中的。