public class HashMultimap<K,V> extends Object implements Serializable
Unlike other implementations (eg, Google's), this is not based around a JDK
HashMap
that uses a JDK Collection
object as its
value. Instead, it maintains the values as part of the hash bucket chain. While
this will increase the time to retrieve or add a value, it is significantly
more memory efficient (particularly when there are a small number of values per
key and you enable set semantics).
Partly as a result, this class does not implement Map
. I
didn't want to put in the extra effort to create a "live" keySet()
.
But more, it would have to be Map<K,Collection<V>>
,
which I thought led to methods that weren't particularly useful.
You can configure this multimap to provide eitherSet or List behavior for its
values, by passing one of the HashMultimap.Behavior
options to the
constructor. With Set semantics, each key-value pair is stored only once;
subsequent puts of the same pair will be ignored. With List semantics, each
key-value pair may be stored multiple times, and the order of reflects the
sequence of puts.
Null keys are not allowed. Null values are.
This class is not threadsafe.
Modifier and Type | Class and Description |
---|---|
static class |
HashMultimap.Behavior
Controls the handling of equal key-value pairs.
|
Constructor and Description |
---|
HashMultimap()
Default constructor: instance will have Set behavior and a small
initial capacity.
|
HashMultimap(HashMultimap.Behavior behavior)
Convenience constructor: creates a stable with small initial capacity and
the specified multi-value behavior.
|
HashMultimap(HashMultimap.Behavior behavior,
int initialCapacity,
double loadFactor)
Base constructor, lets you control everything.
|
Modifier and Type | Method and Description |
---|---|
void |
clear()
Removes all entries from the map.
|
boolean |
containsKey(K key)
Determines whether this object contains a mapping for the given key,
regardless of value.
|
boolean |
containsMapping(K key,
V value)
Determines whether this object contains a the given key-value pair.
|
Collection<Map.Entry<K,V>> |
entries()
Returns the current entries in this map.
|
Iterator<Map.Entry<K,V>> |
entryIterator()
Iterates all entries in the map.
|
boolean |
equals(Object obj) |
V |
get(K key)
Retrieves a single value from the map.
|
Collection<V> |
getAll(K key)
Retrieves all values associated with the specified key.
|
Iterable<V> |
getIterable(K key)
Returns an
Iterable that simply calls getIterator(K) . |
Iterator<V> |
getIterator(K key)
Retrieves an iterator over the values for a given key.
|
protected int |
getTableSize() |
int |
hashCode() |
boolean |
isEmpty()
Convenience method to determine whether the map is empty (size is 0).
|
Set<K> |
keySet()
Returns a set containing the keys from this map.
|
void |
put(K key,
V value)
Adds a key-value pair to the map.
|
V |
remove(K key)
Removes the first entry with the given key.
|
boolean |
remove(K key,
V value)
Removes the first entry with the given key and value.
|
Collection<V> |
removeAll(K key)
Removes all key-value pairs with the given key.
|
Collection<V> |
removeAll(K key,
V value)
Removes all entries with the given key and value
|
int |
size()
Returns the current number of key-value pairs in the map.
|
public HashMultimap(HashMultimap.Behavior behavior, int initialCapacity, double loadFactor)
behavior
- The desired multi-value behavior.initialCapacity
- The initial capacity of the table. This will be rounded
up to the nearest power of 2 that is >= 8.loadFactor
- A factor used to control the expansion of the table: if
the number of occupied buckets is >= this fraction of
current capacity, the table will be doubled.public HashMultimap(HashMultimap.Behavior behavior)
public HashMultimap()
public int size()
public boolean isEmpty()
public void clear()
public V get(K key)
public Collection<V> getAll(K key)
public Iterator<V> getIterator(K key)
getAll(K)
and iterating the results.public Iterable<V> getIterable(K key)
Iterable
that simply calls getIterator(K)
. This
is typically more useful than the latter method, because it can be passed to
a for-each loop.public V remove(K key)
null
if there was no value
associated with the key (or the value was null).public Collection<V> removeAll(K key)
public boolean remove(K key, V value)
true
if the specified key-value pair was removed,
false
if there was no such pair in the map.public Collection<V> removeAll(K key, V value)
true
if the specified key-value pair was removed,
false
if there was no such pair in the map.public boolean containsKey(K key)
public boolean containsMapping(K key, V value)
public Set<K> keySet()
public Collection<Map.Entry<K,V>> entries()
entryIterator()
; see that method for behavior.public Iterator<Map.Entry<K,V>> entryIterator()
protected int getTableSize()