com.gs.collections.impl.multimap.AbstractMultimap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gs-collections Show documentation
Show all versions of gs-collections Show documentation
GS Collections is a collections framework for Java. It has JDK-compatible List, Set and Map
implementations with a rich API and set of utility classes that work with any JDK compatible Collections,
Arrays, Maps or Strings. The iteration protocol was inspired by the Smalltalk collection framework.
/*
* Copyright 2011 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.multimap;
import java.util.Collection;
import java.util.Map;
import com.gs.collections.api.RichIterable;
import com.gs.collections.api.bag.Bag;
import com.gs.collections.api.bag.MutableBag;
import com.gs.collections.api.block.function.Function;
import com.gs.collections.api.block.function.Function0;
import com.gs.collections.api.block.predicate.Predicate;
import com.gs.collections.api.block.procedure.Procedure;
import com.gs.collections.api.block.procedure.Procedure2;
import com.gs.collections.api.map.MapIterable;
import com.gs.collections.api.map.MutableMap;
import com.gs.collections.api.multimap.Multimap;
import com.gs.collections.api.tuple.Pair;
import com.gs.collections.impl.UnmodifiableRichIterable;
import com.gs.collections.impl.block.factory.Functions;
import com.gs.collections.impl.factory.Bags;
import com.gs.collections.impl.map.mutable.UnifiedMap;
import com.gs.collections.impl.tuple.Tuples;
import com.gs.collections.impl.utility.Iterate;
public abstract class AbstractMultimap>
implements Multimap
{
private static final Function, ?> CREATE_COLLECTION_BLOCK = new Function, RichIterable>>()
{
public RichIterable> valueOf(AbstractMultimap, ?, ?> multimap)
{
return multimap.createCollection();
}
};
protected abstract MapIterable getMap();
/**
* Creates the collection of values for a single key.
*
* Collections with weak, soft, or phantom references are not supported.
* Each call to {@code createCollection} should create a new instance.
*
* The returned collection class determines whether duplicate key-value
* pairs are allowed.
*
* @return an empty collection of values
*/
protected abstract C createCollection();
protected Function, C> createCollectionBlock()
{
return (Function, C>) (Function, ?>) CREATE_COLLECTION_BLOCK;
}
// Query Operations
public boolean containsKey(Object key)
{
return this.getMap().containsKey(key);
}
public boolean containsValue(final Object value)
{
return this.getMap().anySatisfy(new Predicate()
{
public boolean accept(C collection)
{
return collection.contains(value);
}
});
}
public boolean containsKeyAndValue(Object key, Object value)
{
C collection = this.getMap().get(key);
return collection != null && collection.contains(value);
}
// Views
public RichIterable keysView()
{
return this.getMap().keysView();
}
public RichIterable> multiValuesView()
{
return this.getMap().valuesView().collect(new Function>()
{
public RichIterable valueOf(C multiValue)
{
return UnmodifiableRichIterable.of(multiValue);
}
});
}
public Bag keyBag()
{
final MutableBag bag = Bags.mutable.of();
this.getMap().forEachKeyValue(new Procedure2()
{
public void value(K key, C value)
{
bag.addOccurrences(key, value.size());
}
});
return bag;
}
public RichIterable valuesView()
{
return this.getMap().valuesView().flatCollect(Functions.>getPassThru());
}
public RichIterable>> keyMultiValuePairsView()
{
return this.getMap().keyValuesView().collect(new Function, Pair>>()
{
public Pair> valueOf(Pair pair)
{
return Tuples.>pair(pair.getOne(), UnmodifiableRichIterable.of(pair.getTwo()));
}
});
}
public RichIterable> keyValuePairsView()
{
return this.keyMultiValuePairsView().flatCollect(new Function>, Iterable>>()
{
public Iterable> valueOf(Pair> pair)
{
return pair.getTwo().collect(new KeyValuePairFunction(pair.getOne()));
}
});
}
// Comparison and hashing
@Override
public boolean equals(Object object)
{
if (object == this)
{
return true;
}
if (object instanceof Multimap)
{
Multimap, ?> that = (Multimap, ?>) object;
return this.getMap().equals(that.toMap());
}
return false;
}
/**
* Returns the hash code for this multimap.
*
* The hash code of a multimap is defined as the hash code of the map view,
* as returned by {@link Multimap#toMap()}.
*
* @see Map#hashCode()
*/
@Override
public int hashCode()
{
return this.getMap().hashCode();
}
/**
* Returns a string representation of the multimap, generated by calling
* {@code toString} on the map returned by {@link Multimap#toMap()}.
*
* @return a string representation of the multimap
*/
@Override
public String toString()
{
return this.getMap().toString();
}
public boolean notEmpty()
{
return !this.isEmpty();
}
public void forEachValue(final Procedure super V> procedure)
{
this.getMap().forEachValue(new Procedure()
{
public void value(C collection)
{
collection.forEach(procedure);
}
});
}
public void forEachKey(Procedure super K> procedure)
{
this.getMap().forEachKey(procedure);
}
public void forEachKeyValue(final Procedure2 procedure)
{
final Procedure2 innerProcedure = new Procedure2()
{
public void value(V value, K key)
{
procedure.value(key, value);
}
};
this.getMap().forEachKeyValue(new Procedure2()
{
public void value(K key, C collection)
{
collection.forEachWith(innerProcedure, key);
}
});
}
public > MutableMap toMap(final Function0 collectionFactory)
{
final MutableMap result = UnifiedMap.newMap();
this.getMap().forEachKeyValue(new Procedure2()
{
public void value(K key, C iterable)
{
R newCollection = collectionFactory.value();
Iterate.addAllTo(iterable, newCollection);
result.put(key, newCollection);
}
});
return result;
}
private static final class KeyValuePairFunction implements Function>
{
private static final long serialVersionUID = 1L;
private final K key;
private KeyValuePairFunction(K key)
{
this.key = key;
}
public Pair valueOf(V value)
{
return Tuples.pair(this.key, value);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy