com.gs.collections.impl.bimap.mutable.AbstractMutableBiMap Maven / Gradle / Ivy
Show all versions of gs-collections Show documentation
/*
* Copyright 2014 Goldman Sachs.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gs.collections.impl.bimap.mutable;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.gs.collections.api.LazyIterable;
import com.gs.collections.api.RichIterable;
import com.gs.collections.api.bag.MutableBag;
import com.gs.collections.api.bimap.ImmutableBiMap;
import com.gs.collections.api.bimap.MutableBiMap;
import com.gs.collections.api.block.function.Function;
import com.gs.collections.api.block.function.Function0;
import com.gs.collections.api.block.function.Function2;
import com.gs.collections.api.block.function.primitive.BooleanFunction;
import com.gs.collections.api.block.function.primitive.ByteFunction;
import com.gs.collections.api.block.function.primitive.CharFunction;
import com.gs.collections.api.block.function.primitive.DoubleFunction;
import com.gs.collections.api.block.function.primitive.DoubleObjectToDoubleFunction;
import com.gs.collections.api.block.function.primitive.FloatFunction;
import com.gs.collections.api.block.function.primitive.FloatObjectToFloatFunction;
import com.gs.collections.api.block.function.primitive.IntFunction;
import com.gs.collections.api.block.function.primitive.IntObjectToIntFunction;
import com.gs.collections.api.block.function.primitive.LongFunction;
import com.gs.collections.api.block.function.primitive.LongObjectToLongFunction;
import com.gs.collections.api.block.function.primitive.ShortFunction;
import com.gs.collections.api.block.predicate.Predicate;
import com.gs.collections.api.block.predicate.Predicate2;
import com.gs.collections.api.block.procedure.Procedure;
import com.gs.collections.api.block.procedure.Procedure2;
import com.gs.collections.api.block.procedure.primitive.ObjectIntProcedure;
import com.gs.collections.api.collection.MutableCollection;
import com.gs.collections.api.collection.primitive.MutableBooleanCollection;
import com.gs.collections.api.collection.primitive.MutableByteCollection;
import com.gs.collections.api.collection.primitive.MutableCharCollection;
import com.gs.collections.api.collection.primitive.MutableDoubleCollection;
import com.gs.collections.api.collection.primitive.MutableFloatCollection;
import com.gs.collections.api.collection.primitive.MutableIntCollection;
import com.gs.collections.api.collection.primitive.MutableLongCollection;
import com.gs.collections.api.collection.primitive.MutableShortCollection;
import com.gs.collections.api.list.MutableList;
import com.gs.collections.api.map.MutableMap;
import com.gs.collections.api.map.sorted.MutableSortedMap;
import com.gs.collections.api.multimap.MutableMultimap;
import com.gs.collections.api.multimap.set.MutableSetMultimap;
import com.gs.collections.api.partition.PartitionMutableCollection;
import com.gs.collections.api.set.MutableSet;
import com.gs.collections.api.set.sorted.MutableSortedSet;
import com.gs.collections.api.tuple.Pair;
import com.gs.collections.impl.block.procedure.MapCollectProcedure;
import com.gs.collections.impl.list.fixed.ArrayAdapter;
import com.gs.collections.impl.map.mutable.UnifiedMap;
import com.gs.collections.impl.utility.Iterate;
import com.gs.collections.impl.utility.MapIterate;
abstract class AbstractMutableBiMap implements MutableBiMap
{
private UnifiedMap delegate;
private AbstractMutableBiMap inverse;
private AbstractMutableBiMap(Map delegate, AbstractMutableBiMap valuesToKeys)
{
this.delegate = UnifiedMap.newMap(delegate);
this.inverse = valuesToKeys;
}
AbstractMutableBiMap(Map map)
{
this.delegate = UnifiedMap.newMap();
this.inverse = new Inverse(UnifiedMap.newMap(), this);
this.putAll(map);
}
AbstractMutableBiMap(Map delegate, Map inverse)
{
this.checkNull(delegate, inverse);
this.checkSame(delegate, inverse);
this.delegate = UnifiedMap.newMap(delegate);
this.inverse = new Inverse(inverse, this);
}
private void checkNull(Map delegate, Map inverse)
{
if (delegate == null || inverse == null)
{
throw new IllegalArgumentException("The delegate maps cannot be null.");
}
}
private void checkSame(Map keysToValues, Map valuesToKeys)
{
if (keysToValues == valuesToKeys)
{
throw new IllegalArgumentException("The delegate maps cannot be same.");
}
}
private static boolean nullSafeEquals(Object value, Object other)
{
if (value == null)
{
if (other == null)
{
return true;
}
}
else if (other == value || value.equals(other))
{
return true;
}
return false;
}
public MutableSetMultimap flip()
{
// TODO: We could optimize this since we know the values are unique
return MapIterate.flip(this);
}
@Override
public MutableBiMap clone()
{
return new HashBiMap(this);
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof Map))
{
return false;
}
Map, ?> map = (Map, ?>) obj;
return this.delegate.equals(map);
}
@Override
public int hashCode()
{
return this.delegate.hashCode();
}
@Override
public String toString()
{
return this.delegate.toString();
}
public V put(K key, V value)
{
if (this.inverse.delegate.containsKey(value))
{
if (AbstractMutableBiMap.nullSafeEquals(key, this.inverse.delegate.get(value)))
{
return value;
}
throw new IllegalArgumentException("Value " + value + " already exists in map!");
}
boolean containsKey = this.delegate.containsKey(key);
V put = this.delegate.put(key, value);
if (containsKey)
{
this.inverse.delegate.removeKey(put);
}
this.inverse.delegate.put(value, key);
return put;
}
public V forcePut(K key, V value)
{
boolean containsValue = this.inverse.delegate.containsKey(value);
if (containsValue)
{
if (AbstractMutableBiMap.nullSafeEquals(key, this.inverse.delegate.get(value)))
{
return value;
}
}
boolean containsKey = this.delegate.containsKey(key);
V put = this.delegate.put(key, value);
if (containsKey)
{
this.inverse.delegate.removeKey(put);
}
K oldKey = this.inverse.delegate.put(value, key);
if (containsValue)
{
this.delegate.removeKey(oldKey);
}
return put;
}
public V remove(Object key)
{
if (!this.delegate.containsKey(key))
{
return null;
}
V oldValue = this.delegate.remove(key);
this.inverse.delegate.remove(oldValue);
return oldValue;
}
public void putAll(Map extends K, ? extends V> map)
{
Set extends Map.Entry extends K, ? extends V>> entries = map.entrySet();
for (Map.Entry extends K, ? extends V> entry : entries)
{
this.put(entry.getKey(), entry.getValue());
}
}
public void clear()
{
this.delegate.clear();
this.inverse.delegate.clear();
}
public Set keySet()
{
return new KeySet();
}
public Collection values()
{
return new ValuesCollection();
}
public Set> entrySet()
{
return new EntrySet();
}
public boolean containsKey(Object key)
{
return this.delegate.containsKey(key);
}
public int size()
{
return this.delegate.size();
}
public boolean isEmpty()
{
return this.delegate.isEmpty();
}
public boolean notEmpty()
{
return this.delegate.notEmpty();
}
public V getFirst()
{
return this.delegate.getFirst();
}
public V getLast()
{
return this.delegate.getLast();
}
public boolean contains(Object object)
{
return this.inverse.delegate.containsKey(object);
}
public boolean containsAllIterable(Iterable> source)
{
return this.inverse.delegate.keysView().containsAllIterable(source);
}
public boolean containsAll(Collection> source)
{
return this.inverse.delegate.keysView().containsAll(source);
}
public boolean containsAllArguments(Object... elements)
{
return this.inverse.delegate.keysView().containsAllArguments(elements);
}
public > R select(Predicate super V> predicate, R target)
{
return this.delegate.select(predicate, target);
}
public RichIterable selectWith(Predicate2 super V, ? super P> predicate, P parameter)
{
return this.delegate.selectWith(predicate, parameter);
}
public RichIterable rejectWith(Predicate2 super V, ? super P> predicate, P parameter)
{
return this.delegate.rejectWith(predicate, parameter);
}
public MutableCollection collect(Function super V, ? extends VV> function)
{
return this.delegate.collect(function);
}
public MutableBooleanCollection collectBoolean(BooleanFunction super V> booleanFunction)
{
return this.delegate.collectBoolean(booleanFunction);
}
public R collectBoolean(BooleanFunction super V> booleanFunction, R target)
{
return this.delegate.collectBoolean(booleanFunction, target);
}
public MutableByteCollection collectByte(ByteFunction super V> byteFunction)
{
return this.delegate.collectByte(byteFunction);
}
public R collectByte(ByteFunction super V> byteFunction, R target)
{
return this.delegate.collectByte(byteFunction, target);
}
public MutableCharCollection collectChar(CharFunction super V> charFunction)
{
return this.delegate.collectChar(charFunction);
}
public R collectChar(CharFunction super V> charFunction, R target)
{
return this.delegate.collectChar(charFunction, target);
}
public > R selectWith(Predicate2 super V, ? super P> predicate, P parameter, R targetCollection)
{
return this.delegate.selectWith(predicate, parameter, targetCollection);
}
public MutableDoubleCollection collectDouble(DoubleFunction super V> doubleFunction)
{
return this.delegate.collectDouble(doubleFunction);
}
public R collectDouble(DoubleFunction super V> doubleFunction, R target)
{
return this.delegate.collectDouble(doubleFunction, target);
}
public MutableFloatCollection collectFloat(FloatFunction super V> floatFunction)
{
return this.delegate.collectFloat(floatFunction);
}
public R collectFloat(FloatFunction super V> floatFunction, R target)
{
return this.delegate.collectFloat(floatFunction, target);
}
public MutableIntCollection collectInt(IntFunction super V> intFunction)
{
return this.delegate.collectInt(intFunction);
}
public R collectInt(IntFunction super V> intFunction, R target)
{
return this.delegate.collectInt(intFunction, target);
}
public MutableLongCollection collectLong(LongFunction super V> longFunction)
{
return this.delegate.collectLong(longFunction);
}
public R collectLong(LongFunction super V> longFunction, R target)
{
return this.delegate.collectLong(longFunction, target);
}
public MutableShortCollection collectShort(ShortFunction super V> shortFunction)
{
return this.delegate.collectShort(shortFunction);
}
public R collectShort(ShortFunction super V> shortFunction, R target)
{
return this.delegate.collectShort(shortFunction, target);
}
public MutableCollection collectIf(Predicate super V> predicate, Function super V, ? extends VV> function)
{
return this.delegate.collectIf(predicate, function);
}
public MutableCollection reject(Predicate super V> predicate)
{
return this.delegate.reject(predicate);
}
public MutableCollection select(Predicate super V> predicate)
{
return this.delegate.select(predicate);
}
public PartitionMutableCollection partition(Predicate super V> predicate)
{
return this.delegate.partition(predicate);
}
public PartitionMutableCollection partitionWith(Predicate2 super V, ? super P> predicate, P parameter)
{
return this.delegate.partitionWith(predicate, parameter);
}
public MutableCollection selectInstancesOf(Class clazz)
{
return this.delegate.selectInstancesOf(clazz);
}
public MutableCollection> zipWithIndex()
{
return this.delegate.zipWithIndex();
}
public > R reject(Predicate super V> predicate, R target)
{
return this.delegate.reject(predicate, target);
}
public > R rejectWith(Predicate2 super V, ? super P> predicate, P parameter, R targetCollection)
{
return this.delegate.rejectWith(predicate, parameter, targetCollection);
}
public MutableMap aggregateBy(Function super V, ? extends K2> groupBy, Function0 extends V2> zeroValueFactory, Function2 super V2, ? super V, ? extends V2> nonMutatingAggregator)
{
return this.delegate.aggregateBy(groupBy, zeroValueFactory, nonMutatingAggregator);
}
public > R collect(Function super V, ? extends VV> function, R target)
{
return this.delegate.collect(function, target);
}
public MutableList collectWith(Function2 super V, ? super P, ? extends VV> function, P parameter)
{
return this.delegate.collectWith(function, parameter);
}
public > R collectWith(Function2 super V, ? super P, ? extends VV> function, P parameter, R targetCollection)
{
return this.delegate.collectWith(function, parameter, targetCollection);
}
public > R collectIf(Predicate super V> predicate, Function super V, ? extends VV> function, R target)
{
return this.delegate.collectIf(predicate, function, target);
}
public MutableCollection flatCollect(Function super V, ? extends Iterable> function)
{
return this.delegate.flatCollect(function);
}
public > R flatCollect(Function super V, ? extends Iterable> function, R target)
{
return this.delegate.flatCollect(function, target);
}
public V detect(Predicate super V> predicate)
{
return this.delegate.detect(predicate);
}
public V detectWith(Predicate2 super V, ? super P> predicate, P parameter)
{
return this.delegate.detectWith(predicate, parameter);
}
public V detectIfNone(Predicate super V> predicate, Function0 extends V> function)
{
return this.delegate.detectIfNone(predicate, function);
}
public
V detectWithIfNone(Predicate2 super V, ? super P> predicate, P parameter, Function0 extends V> function)
{
return this.delegate.detectWithIfNone(predicate, parameter, function);
}
public int count(Predicate super V> predicate)
{
return this.delegate.count(predicate);
}
public
int countWith(Predicate2 super V, ? super P> predicate, P parameter)
{
return this.delegate.countWith(predicate, parameter);
}
public boolean anySatisfy(Predicate super V> predicate)
{
return this.delegate.anySatisfy(predicate);
}
public
boolean anySatisfyWith(Predicate2 super V, ? super P> predicate, P parameter)
{
return this.delegate.anySatisfyWith(predicate, parameter);
}
public boolean allSatisfy(Predicate super V> predicate)
{
return this.delegate.allSatisfy(predicate);
}
public
boolean allSatisfyWith(Predicate2 super V, ? super P> predicate, P parameter)
{
return this.delegate.allSatisfyWith(predicate, parameter);
}
public boolean noneSatisfy(Predicate super V> predicate)
{
return this.delegate.noneSatisfy(predicate);
}
public
boolean noneSatisfyWith(Predicate2 super V, ? super P> predicate, P parameter)
{
return this.delegate.noneSatisfyWith(predicate, parameter);
}
public IV injectInto(IV injectedValue, Function2 super IV, ? super V, ? extends IV> function)
{
return this.delegate.injectInto(injectedValue, function);
}
public int injectInto(int injectedValue, IntObjectToIntFunction super V> function)
{
return this.delegate.injectInto(injectedValue, function);
}
public long injectInto(long injectedValue, LongObjectToLongFunction super V> function)
{
return this.delegate.injectInto(injectedValue, function);
}
public float injectInto(float injectedValue, FloatObjectToFloatFunction super V> function)
{
return this.delegate.injectInto(injectedValue, function);
}
public double injectInto(double injectedValue, DoubleObjectToDoubleFunction super V> function)
{
return this.delegate.injectInto(injectedValue, function);
}
public MutableList toList()
{
return this.delegate.toList();
}
public MutableList toSortedList()
{
return this.delegate.toSortedList();
}
public MutableList toSortedList(Comparator super V> comparator)
{
return this.delegate.toSortedList(comparator);
}
public > MutableList toSortedListBy(Function super V, ? extends VV> function)
{
return this.delegate.toSortedListBy(function);
}
public MutableSet toSet()
{
return this.delegate.toSet();
}
public MutableSortedSet toSortedSet()
{
return this.delegate.toSortedSet();
}
public MutableSortedSet toSortedSet(Comparator super V> comparator)
{
return this.delegate.toSortedSet(comparator);
}
public > MutableSortedSet toSortedSetBy(Function super V, ? extends VV> function)
{
return this.delegate.toSortedSetBy(function);
}
public MutableBag toBag()
{
return this.delegate.toBag();
}
public MutableMap toMap(Function super V, ? extends NK> keyFunction, Function super V, ? extends NV> valueFunction)
{
return this.delegate.toMap(keyFunction, valueFunction);
}
public MutableSortedMap toSortedMap(Function super V, ? extends NK> keyFunction, Function super V, ? extends NV> valueFunction)
{
return this.delegate.toSortedMap(keyFunction, valueFunction);
}
public MutableSortedMap toSortedMap(Comparator super NK> comparator, Function super V, ? extends NK> keyFunction, Function super V, ? extends NV> valueFunction)
{
return this.delegate.toSortedMap(comparator, keyFunction, valueFunction);
}
public LazyIterable asLazy()
{
return this.delegate.asLazy();
}
public Object[] toArray()
{
return this.delegate.toArray();
}
public T[] toArray(T[] a)
{
return this.delegate.toArray(a);
}
public V min(Comparator super V> comparator)
{
return this.delegate.min(comparator);
}
public V max(Comparator super V> comparator)
{
return this.delegate.max(comparator);
}
public V min()
{
return this.delegate.min();
}
public V max()
{
return this.delegate.max();
}
public > V minBy(Function super V, ? extends VV> function)
{
return this.delegate.minBy(function);
}
public > V maxBy(Function super V, ? extends VV> function)
{
return this.delegate.maxBy(function);
}
public long sumOfInt(IntFunction super V> function)
{
return this.delegate.sumOfInt(function);
}
public double sumOfFloat(FloatFunction super V> function)
{
return this.delegate.sumOfFloat(function);
}
public long sumOfLong(LongFunction super V> function)
{
return this.delegate.sumOfLong(function);
}
public double sumOfDouble(DoubleFunction super V> function)
{
return this.delegate.sumOfDouble(function);
}
public String makeString()
{
return this.delegate.makeString();
}
public String makeString(String separator)
{
return this.delegate.makeString(separator);
}
public String makeString(String start, String separator, String end)
{
return this.delegate.makeString(start, separator, end);
}
public void appendString(Appendable appendable)
{
this.delegate.appendString(appendable);
}
public void appendString(Appendable appendable, String separator)
{
this.delegate.appendString(appendable, separator);
}
public void appendString(Appendable appendable, String start, String separator, String end)
{
this.delegate.appendString(appendable, start, separator, end);
}
public MutableMultimap groupBy(Function super V, ? extends VV> function)
{
return this.delegate.groupBy(function);
}
public > R groupBy(Function super V, ? extends VV> function, R target)
{
return this.delegate.groupBy(function, target);
}
public MutableMultimap groupByEach(Function super V, ? extends Iterable> function)
{
return this.delegate.groupByEach(function);
}
public > R groupByEach(Function super V, ? extends Iterable> function, R target)
{
return this.delegate.groupByEach(function, target);
}
public MutableMap groupByUniqueKey(Function super V, ? extends VV> function)
{
return this.delegate.groupByUniqueKey(function);
}
public MutableCollection> zip(Iterable that)
{
return this.delegate.zip(that);
}
public >> R zip(Iterable that, R target)
{
return this.delegate.zip(that, target);
}
public >> R zipWithIndex(R target)
{
return this.delegate.zipWithIndex(target);
}
public RichIterable> chunk(int size)
{
return this.delegate.chunk(size);
}
public MutableMap aggregateInPlaceBy(Function super V, ? extends K2> groupBy, Function0 extends V2> zeroValueFactory, Procedure2 super V2, ? super V> mutatingAggregator)
{
return this.delegate.aggregateInPlaceBy(groupBy, zeroValueFactory, mutatingAggregator);
}
public boolean containsValue(Object value)
{
return this.inverse.delegate.containsKey(value);
}
public V get(Object key)
{
return this.delegate.get(key);
}
public HashBiMap select(final Predicate2 super K, ? super V> predicate)
{
final HashBiMap result = HashBiMap.newMap();
this.delegate.forEachKeyValue(new Procedure2()
{
public void value(K key, V value)
{
if (predicate.accept(key, value))
{
result.put(key, value);
}
}
});
return result;
}
public HashBiMap collectValues(final Function2 super K, ? super V, ? extends R> function)
{
final HashBiMap result = HashBiMap.newMap();
this.delegate.forEachKeyValue(new Procedure2()
{
public void value(K key, V value)
{
result.put(key, function.value(key, value));
}
});
return result;
}
public HashBiMap collect(final Function2 super K, ? super V, Pair> function)
{
final HashBiMap result = HashBiMap.newMap();
this.delegate.forEachKeyValue(new Procedure2()
{
public void value(K key, V value)
{
Pair pair = function.value(key, value);
result.put(pair.getOne(), pair.getTwo());
}
});
return result;
}
public HashBiMap reject(final Predicate2 super K, ? super V> predicate)
{
final HashBiMap result = HashBiMap.newMap();
this.delegate.forEachKeyValue(new Procedure2()
{
public void value(K key, V value)
{
if (!predicate.accept(key, value))
{
result.put(key, value);
}
}
});
return result;
}
public void forEachValue(Procedure super V> procedure)
{
this.inverse.delegate.forEachKey(procedure);
}
public void forEachKey(Procedure super K> procedure)
{
this.delegate.forEachKey(procedure);
}
public void forEachKeyValue(Procedure2 super K, ? super V> procedure)
{
this.delegate.forEachKeyValue(procedure);
}
public MutableBiMap flipUniqueValues()
{
return new HashBiMap(this.inverse());
}
public V getIfAbsent(K key, Function0 extends V> function)
{
return this.delegate.getIfAbsent(key, function);
}
public V getIfAbsentValue(K key, V value)
{
return this.delegate.getIfAbsentValue(key, value);
}
public