654 lines
22 KiB
Java
654 lines
22 KiB
Java
package com.google.common.collect;
|
|
|
|
import com.google.common.base.Objects;
|
|
import com.google.common.base.Preconditions;
|
|
import com.google.common.collect.Maps;
|
|
import java.io.IOException;
|
|
import java.io.ObjectInputStream;
|
|
import java.io.ObjectOutputStream;
|
|
import java.io.Serializable;
|
|
import java.util.AbstractMap;
|
|
import java.util.Arrays;
|
|
import java.util.ConcurrentModificationException;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
import java.util.NoSuchElementException;
|
|
import java.util.Set;
|
|
|
|
/* loaded from: classes.dex */
|
|
public final class HashBiMap<K, V> extends Maps.IteratorBasedAbstractMap<K, V> implements BiMap<K, V>, Serializable {
|
|
private static final double LOAD_FACTOR = 1.0d;
|
|
private static final long serialVersionUID = 0;
|
|
private transient BiEntry<K, V> firstInKeyInsertionOrder;
|
|
private transient BiEntry<K, V>[] hashTableKToV;
|
|
private transient BiEntry<K, V>[] hashTableVToK;
|
|
private transient BiMap<V, K> inverse;
|
|
private transient BiEntry<K, V> lastInKeyInsertionOrder;
|
|
private transient int mask;
|
|
private transient int modCount;
|
|
private transient int size;
|
|
|
|
private static final class BiEntry<K, V> extends ImmutableEntry<K, V> {
|
|
final int c;
|
|
final int d;
|
|
BiEntry<K, V> e;
|
|
BiEntry<K, V> f;
|
|
BiEntry<K, V> g;
|
|
BiEntry<K, V> h;
|
|
|
|
BiEntry(K k, int i, V v, int i2) {
|
|
super(k, v);
|
|
this.c = i;
|
|
this.d = i2;
|
|
}
|
|
}
|
|
|
|
private final class Inverse extends AbstractMap<V, K> implements BiMap<V, K>, Serializable {
|
|
|
|
/* renamed from: com.google.common.collect.HashBiMap$Inverse$1, reason: invalid class name */
|
|
class AnonymousClass1 extends Maps.EntrySet<V, K> {
|
|
AnonymousClass1() {
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.EntrySet
|
|
Map<V, K> c() {
|
|
return Inverse.this;
|
|
}
|
|
|
|
@Override // java.util.AbstractCollection, java.util.Collection, java.lang.Iterable, java.util.Set
|
|
public Iterator<Map.Entry<V, K>> iterator() {
|
|
return new HashBiMap<K, V>.Itr<Map.Entry<V, K>>() { // from class: com.google.common.collect.HashBiMap.Inverse.1.1
|
|
|
|
/* renamed from: com.google.common.collect.HashBiMap$Inverse$1$1$InverseEntry */
|
|
class InverseEntry extends AbstractMapEntry<V, K> {
|
|
BiEntry<K, V> a;
|
|
|
|
InverseEntry(BiEntry<K, V> biEntry) {
|
|
this.a = biEntry;
|
|
}
|
|
|
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
|
public V getKey() {
|
|
return this.a.b;
|
|
}
|
|
|
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
|
public K getValue() {
|
|
return this.a.a;
|
|
}
|
|
|
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
|
public K setValue(K k) {
|
|
K k2 = this.a.a;
|
|
int a = Hashing.a(k);
|
|
if (a == this.a.c && Objects.a(k, k2)) {
|
|
return k;
|
|
}
|
|
Preconditions.a(HashBiMap.this.seekByKey(k, a) == null, "value already present: %s", k);
|
|
HashBiMap.this.delete(this.a);
|
|
BiEntry<K, V> biEntry = this.a;
|
|
BiEntry<K, V> biEntry2 = new BiEntry<>(k, a, biEntry.b, biEntry.d);
|
|
this.a = biEntry2;
|
|
HashBiMap.this.insert(biEntry2, null);
|
|
C00071 c00071 = C00071.this;
|
|
c00071.c = HashBiMap.this.modCount;
|
|
return k2;
|
|
}
|
|
}
|
|
|
|
{
|
|
HashBiMap hashBiMap = HashBiMap.this;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
@Override // com.google.common.collect.HashBiMap.Itr
|
|
public Map.Entry<V, K> a(BiEntry<K, V> biEntry) {
|
|
return new InverseEntry(biEntry);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
private final class InverseKeySet extends Maps.KeySet<V, K> {
|
|
InverseKeySet() {
|
|
super(Inverse.this);
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.KeySet, java.util.AbstractCollection, java.util.Collection, java.lang.Iterable, java.util.Set
|
|
public Iterator<V> iterator() {
|
|
return new HashBiMap<K, V>.Itr<V>(this) { // from class: com.google.common.collect.HashBiMap.Inverse.InverseKeySet.1
|
|
{
|
|
HashBiMap hashBiMap = HashBiMap.this;
|
|
}
|
|
|
|
@Override // com.google.common.collect.HashBiMap.Itr
|
|
V a(BiEntry<K, V> biEntry) {
|
|
return biEntry.b;
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.KeySet, java.util.AbstractCollection, java.util.Collection, java.util.Set
|
|
public boolean remove(Object obj) {
|
|
BiEntry seekByValue = HashBiMap.this.seekByValue(obj, Hashing.a(obj));
|
|
if (seekByValue == null) {
|
|
return false;
|
|
}
|
|
HashBiMap.this.delete(seekByValue);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private Inverse() {
|
|
}
|
|
|
|
BiMap<K, V> a() {
|
|
return HashBiMap.this;
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public void clear() {
|
|
a().clear();
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public boolean containsKey(Object obj) {
|
|
return a().containsValue(obj);
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public Set<Map.Entry<V, K>> entrySet() {
|
|
return new AnonymousClass1();
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public K get(Object obj) {
|
|
return (K) Maps.a(HashBiMap.this.seekByValue(obj, Hashing.a(obj)));
|
|
}
|
|
|
|
@Override // com.google.common.collect.BiMap
|
|
public BiMap<K, V> inverse() {
|
|
return a();
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public Set<V> keySet() {
|
|
return new InverseKeySet();
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public K put(V v, K k) {
|
|
return (K) HashBiMap.this.putInverse(v, k, false);
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public K remove(Object obj) {
|
|
BiEntry seekByValue = HashBiMap.this.seekByValue(obj, Hashing.a(obj));
|
|
if (seekByValue == null) {
|
|
return null;
|
|
}
|
|
HashBiMap.this.delete(seekByValue);
|
|
seekByValue.h = null;
|
|
seekByValue.g = null;
|
|
return seekByValue.a;
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public int size() {
|
|
return HashBiMap.this.size;
|
|
}
|
|
|
|
Object writeReplace() {
|
|
return new InverseSerializedForm(HashBiMap.this);
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public Set<K> values() {
|
|
return a().keySet();
|
|
}
|
|
}
|
|
|
|
private static final class InverseSerializedForm<K, V> implements Serializable {
|
|
private final HashBiMap<K, V> a;
|
|
|
|
InverseSerializedForm(HashBiMap<K, V> hashBiMap) {
|
|
this.a = hashBiMap;
|
|
}
|
|
|
|
Object readResolve() {
|
|
return this.a.inverse();
|
|
}
|
|
}
|
|
|
|
abstract class Itr<T> implements Iterator<T> {
|
|
BiEntry<K, V> a;
|
|
BiEntry<K, V> b = null;
|
|
int c;
|
|
|
|
Itr() {
|
|
this.a = HashBiMap.this.firstInKeyInsertionOrder;
|
|
this.c = HashBiMap.this.modCount;
|
|
}
|
|
|
|
abstract T a(BiEntry<K, V> biEntry);
|
|
|
|
@Override // java.util.Iterator
|
|
public boolean hasNext() {
|
|
if (HashBiMap.this.modCount == this.c) {
|
|
return this.a != null;
|
|
}
|
|
throw new ConcurrentModificationException();
|
|
}
|
|
|
|
@Override // java.util.Iterator
|
|
public T next() {
|
|
if (!hasNext()) {
|
|
throw new NoSuchElementException();
|
|
}
|
|
BiEntry<K, V> biEntry = this.a;
|
|
this.a = biEntry.g;
|
|
this.b = biEntry;
|
|
return a(biEntry);
|
|
}
|
|
|
|
@Override // java.util.Iterator
|
|
public void remove() {
|
|
if (HashBiMap.this.modCount != this.c) {
|
|
throw new ConcurrentModificationException();
|
|
}
|
|
CollectPreconditions.a(this.b != null);
|
|
HashBiMap.this.delete(this.b);
|
|
this.c = HashBiMap.this.modCount;
|
|
this.b = null;
|
|
}
|
|
}
|
|
|
|
private final class KeySet extends Maps.KeySet<K, V> {
|
|
KeySet() {
|
|
super(HashBiMap.this);
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.KeySet, java.util.AbstractCollection, java.util.Collection, java.lang.Iterable, java.util.Set
|
|
public Iterator<K> iterator() {
|
|
return new HashBiMap<K, V>.Itr<K>(this) { // from class: com.google.common.collect.HashBiMap.KeySet.1
|
|
{
|
|
HashBiMap hashBiMap = HashBiMap.this;
|
|
}
|
|
|
|
@Override // com.google.common.collect.HashBiMap.Itr
|
|
K a(BiEntry<K, V> biEntry) {
|
|
return biEntry.a;
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.KeySet, java.util.AbstractCollection, java.util.Collection, java.util.Set
|
|
public boolean remove(Object obj) {
|
|
BiEntry seekByKey = HashBiMap.this.seekByKey(obj, Hashing.a(obj));
|
|
if (seekByKey == null) {
|
|
return false;
|
|
}
|
|
HashBiMap.this.delete(seekByKey);
|
|
seekByKey.h = null;
|
|
seekByKey.g = null;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private HashBiMap(int i) {
|
|
init(i);
|
|
}
|
|
|
|
public static <K, V> HashBiMap<K, V> create() {
|
|
return create(16);
|
|
}
|
|
|
|
private BiEntry<K, V>[] createTable(int i) {
|
|
return new BiEntry[i];
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void delete(BiEntry<K, V> biEntry) {
|
|
BiEntry<K, V> biEntry2;
|
|
int i = biEntry.c & this.mask;
|
|
BiEntry<K, V> biEntry3 = null;
|
|
BiEntry<K, V> biEntry4 = null;
|
|
for (BiEntry<K, V> biEntry5 = this.hashTableKToV[i]; biEntry5 != biEntry; biEntry5 = biEntry5.e) {
|
|
biEntry4 = biEntry5;
|
|
}
|
|
if (biEntry4 == null) {
|
|
this.hashTableKToV[i] = biEntry.e;
|
|
} else {
|
|
biEntry4.e = biEntry.e;
|
|
}
|
|
int i2 = biEntry.d & this.mask;
|
|
BiEntry<K, V> biEntry6 = this.hashTableVToK[i2];
|
|
while (true) {
|
|
biEntry2 = biEntry3;
|
|
biEntry3 = biEntry6;
|
|
if (biEntry3 == biEntry) {
|
|
break;
|
|
} else {
|
|
biEntry6 = biEntry3.f;
|
|
}
|
|
}
|
|
if (biEntry2 == null) {
|
|
this.hashTableVToK[i2] = biEntry.f;
|
|
} else {
|
|
biEntry2.f = biEntry.f;
|
|
}
|
|
BiEntry<K, V> biEntry7 = biEntry.h;
|
|
if (biEntry7 == null) {
|
|
this.firstInKeyInsertionOrder = biEntry.g;
|
|
} else {
|
|
biEntry7.g = biEntry.g;
|
|
}
|
|
BiEntry<K, V> biEntry8 = biEntry.g;
|
|
if (biEntry8 == null) {
|
|
this.lastInKeyInsertionOrder = biEntry.h;
|
|
} else {
|
|
biEntry8.h = biEntry.h;
|
|
}
|
|
this.size--;
|
|
this.modCount++;
|
|
}
|
|
|
|
private void init(int i) {
|
|
CollectPreconditions.a(i, "expectedSize");
|
|
int a = Hashing.a(i, LOAD_FACTOR);
|
|
this.hashTableKToV = createTable(a);
|
|
this.hashTableVToK = createTable(a);
|
|
this.firstInKeyInsertionOrder = null;
|
|
this.lastInKeyInsertionOrder = null;
|
|
this.size = 0;
|
|
this.mask = a - 1;
|
|
this.modCount = 0;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void insert(BiEntry<K, V> biEntry, BiEntry<K, V> biEntry2) {
|
|
int i = biEntry.c;
|
|
int i2 = this.mask;
|
|
int i3 = i & i2;
|
|
BiEntry<K, V>[] biEntryArr = this.hashTableKToV;
|
|
biEntry.e = biEntryArr[i3];
|
|
biEntryArr[i3] = biEntry;
|
|
int i4 = biEntry.d & i2;
|
|
BiEntry<K, V>[] biEntryArr2 = this.hashTableVToK;
|
|
biEntry.f = biEntryArr2[i4];
|
|
biEntryArr2[i4] = biEntry;
|
|
if (biEntry2 == null) {
|
|
BiEntry<K, V> biEntry3 = this.lastInKeyInsertionOrder;
|
|
biEntry.h = biEntry3;
|
|
biEntry.g = null;
|
|
if (biEntry3 == null) {
|
|
this.firstInKeyInsertionOrder = biEntry;
|
|
} else {
|
|
biEntry3.g = biEntry;
|
|
}
|
|
this.lastInKeyInsertionOrder = biEntry;
|
|
} else {
|
|
biEntry.h = biEntry2.h;
|
|
BiEntry<K, V> biEntry4 = biEntry.h;
|
|
if (biEntry4 == null) {
|
|
this.firstInKeyInsertionOrder = biEntry;
|
|
} else {
|
|
biEntry4.g = biEntry;
|
|
}
|
|
biEntry.g = biEntry2.g;
|
|
BiEntry<K, V> biEntry5 = biEntry.g;
|
|
if (biEntry5 == null) {
|
|
this.lastInKeyInsertionOrder = biEntry;
|
|
} else {
|
|
biEntry5.h = biEntry;
|
|
}
|
|
}
|
|
this.size++;
|
|
this.modCount++;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public K putInverse(V v, K k, boolean z) {
|
|
int a = Hashing.a(v);
|
|
int a2 = Hashing.a(k);
|
|
BiEntry<K, V> seekByValue = seekByValue(v, a);
|
|
if (seekByValue != null && a2 == seekByValue.c && Objects.a(k, seekByValue.a)) {
|
|
return k;
|
|
}
|
|
BiEntry<K, V> seekByKey = seekByKey(k, a2);
|
|
if (seekByKey != null) {
|
|
if (!z) {
|
|
throw new IllegalArgumentException("value already present: " + k);
|
|
}
|
|
delete(seekByKey);
|
|
}
|
|
if (seekByValue != null) {
|
|
delete(seekByValue);
|
|
}
|
|
insert(new BiEntry<>(k, a2, v, a), seekByKey);
|
|
if (seekByKey != null) {
|
|
seekByKey.h = null;
|
|
seekByKey.g = null;
|
|
}
|
|
rehashIfNecessary();
|
|
return (K) Maps.a(seekByValue);
|
|
}
|
|
|
|
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
|
|
objectInputStream.defaultReadObject();
|
|
init(16);
|
|
Serialization.a(this, objectInputStream, Serialization.a(objectInputStream));
|
|
}
|
|
|
|
private void rehashIfNecessary() {
|
|
BiEntry<K, V>[] biEntryArr = this.hashTableKToV;
|
|
if (Hashing.a(this.size, biEntryArr.length, LOAD_FACTOR)) {
|
|
int length = biEntryArr.length * 2;
|
|
this.hashTableKToV = createTable(length);
|
|
this.hashTableVToK = createTable(length);
|
|
this.mask = length - 1;
|
|
this.size = 0;
|
|
for (BiEntry<K, V> biEntry = this.firstInKeyInsertionOrder; biEntry != null; biEntry = biEntry.g) {
|
|
insert(biEntry, biEntry);
|
|
}
|
|
this.modCount++;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public BiEntry<K, V> seekByKey(Object obj, int i) {
|
|
for (BiEntry<K, V> biEntry = this.hashTableKToV[this.mask & i]; biEntry != null; biEntry = biEntry.e) {
|
|
if (i == biEntry.c && Objects.a(obj, biEntry.a)) {
|
|
return biEntry;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public BiEntry<K, V> seekByValue(Object obj, int i) {
|
|
for (BiEntry<K, V> biEntry = this.hashTableVToK[this.mask & i]; biEntry != null; biEntry = biEntry.f) {
|
|
if (i == biEntry.d && Objects.a(obj, biEntry.b)) {
|
|
return biEntry;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
|
|
objectOutputStream.defaultWriteObject();
|
|
Serialization.a(this, objectOutputStream);
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.IteratorBasedAbstractMap, java.util.AbstractMap, java.util.Map
|
|
public void clear() {
|
|
this.size = 0;
|
|
Arrays.fill(this.hashTableKToV, (Object) null);
|
|
Arrays.fill(this.hashTableVToK, (Object) null);
|
|
this.firstInKeyInsertionOrder = null;
|
|
this.lastInKeyInsertionOrder = null;
|
|
this.modCount++;
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public boolean containsKey(Object obj) {
|
|
return seekByKey(obj, Hashing.a(obj)) != null;
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public boolean containsValue(Object obj) {
|
|
return seekByValue(obj, Hashing.a(obj)) != null;
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.IteratorBasedAbstractMap
|
|
Iterator<Map.Entry<K, V>> entryIterator() {
|
|
return new HashBiMap<K, V>.Itr<Map.Entry<K, V>>() { // from class: com.google.common.collect.HashBiMap.1
|
|
|
|
/* renamed from: com.google.common.collect.HashBiMap$1$MapEntry */
|
|
class MapEntry extends AbstractMapEntry<K, V> {
|
|
BiEntry<K, V> a;
|
|
|
|
MapEntry(BiEntry<K, V> biEntry) {
|
|
this.a = biEntry;
|
|
}
|
|
|
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
|
public K getKey() {
|
|
return this.a.a;
|
|
}
|
|
|
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
|
public V getValue() {
|
|
return this.a.b;
|
|
}
|
|
|
|
@Override // com.google.common.collect.AbstractMapEntry, java.util.Map.Entry
|
|
public V setValue(V v) {
|
|
V v2 = this.a.b;
|
|
int a = Hashing.a(v);
|
|
if (a == this.a.d && Objects.a(v, v2)) {
|
|
return v;
|
|
}
|
|
Preconditions.a(HashBiMap.this.seekByValue(v, a) == null, "value already present: %s", v);
|
|
HashBiMap.this.delete(this.a);
|
|
BiEntry<K, V> biEntry = this.a;
|
|
BiEntry<K, V> biEntry2 = new BiEntry<>(biEntry.a, biEntry.c, v, a);
|
|
HashBiMap.this.insert(biEntry2, this.a);
|
|
BiEntry<K, V> biEntry3 = this.a;
|
|
biEntry3.h = null;
|
|
biEntry3.g = null;
|
|
AnonymousClass1 anonymousClass1 = AnonymousClass1.this;
|
|
anonymousClass1.c = HashBiMap.this.modCount;
|
|
AnonymousClass1 anonymousClass12 = AnonymousClass1.this;
|
|
if (anonymousClass12.b == this.a) {
|
|
anonymousClass12.b = biEntry2;
|
|
}
|
|
this.a = biEntry2;
|
|
return v2;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
@Override // com.google.common.collect.HashBiMap.Itr
|
|
public Map.Entry<K, V> a(BiEntry<K, V> biEntry) {
|
|
return new MapEntry(biEntry);
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.IteratorBasedAbstractMap, java.util.AbstractMap, java.util.Map
|
|
public /* bridge */ /* synthetic */ Set entrySet() {
|
|
return super.entrySet();
|
|
}
|
|
|
|
public V forcePut(K k, V v) {
|
|
return put(k, v, true);
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public V get(Object obj) {
|
|
return (V) Maps.c(seekByKey(obj, Hashing.a(obj)));
|
|
}
|
|
|
|
@Override // com.google.common.collect.BiMap
|
|
public BiMap<V, K> inverse() {
|
|
BiMap<V, K> biMap = this.inverse;
|
|
if (biMap != null) {
|
|
return biMap;
|
|
}
|
|
Inverse inverse = new Inverse();
|
|
this.inverse = inverse;
|
|
return inverse;
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public Set<K> keySet() {
|
|
return new KeySet();
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public V put(K k, V v) {
|
|
return put(k, v, false);
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public V remove(Object obj) {
|
|
BiEntry<K, V> seekByKey = seekByKey(obj, Hashing.a(obj));
|
|
if (seekByKey == null) {
|
|
return null;
|
|
}
|
|
delete(seekByKey);
|
|
seekByKey.h = null;
|
|
seekByKey.g = null;
|
|
return seekByKey.b;
|
|
}
|
|
|
|
@Override // com.google.common.collect.Maps.IteratorBasedAbstractMap, java.util.AbstractMap, java.util.Map
|
|
public int size() {
|
|
return this.size;
|
|
}
|
|
|
|
public static <K, V> HashBiMap<K, V> create(int i) {
|
|
return new HashBiMap<>(i);
|
|
}
|
|
|
|
private V put(K k, V v, boolean z) {
|
|
int a = Hashing.a(k);
|
|
int a2 = Hashing.a(v);
|
|
BiEntry<K, V> seekByKey = seekByKey(k, a);
|
|
if (seekByKey != null && a2 == seekByKey.d && Objects.a(v, seekByKey.b)) {
|
|
return v;
|
|
}
|
|
BiEntry<K, V> seekByValue = seekByValue(v, a2);
|
|
if (seekByValue != null) {
|
|
if (!z) {
|
|
throw new IllegalArgumentException("value already present: " + v);
|
|
}
|
|
delete(seekByValue);
|
|
}
|
|
BiEntry<K, V> biEntry = new BiEntry<>(k, a, v, a2);
|
|
if (seekByKey == null) {
|
|
insert(biEntry, null);
|
|
rehashIfNecessary();
|
|
return null;
|
|
}
|
|
delete(seekByKey);
|
|
insert(biEntry, seekByKey);
|
|
seekByKey.h = null;
|
|
seekByKey.g = null;
|
|
rehashIfNecessary();
|
|
return seekByKey.b;
|
|
}
|
|
|
|
@Override // java.util.AbstractMap, java.util.Map
|
|
public Set<V> values() {
|
|
return inverse().keySet();
|
|
}
|
|
|
|
public static <K, V> HashBiMap<K, V> create(Map<? extends K, ? extends V> map) {
|
|
HashBiMap<K, V> create = create(map.size());
|
|
create.putAll(map);
|
|
return create;
|
|
}
|
|
}
|