package uk.ac.rhul.cs.collections; import java.util.*; /** * Base implementation of a multimap. * * This object contains implementation for most of the methods required * by the {@link Multimap} interface without knowing what type of map * is used to back the multimap. * * @author tamas */ public abstract class MultimapBase<K, V> implements Multimap<K, V> { /** * Internal storage for the key-value pairs. */ protected Map<K, Collection<V>> data; public MultimapBase() { initializeStorage(); } public void clear() { data.clear(); } public boolean containsKey(Object key) { Collection<V> values = data.get(key); return values != null && values.size() > 0; } public Collection<V> get(K key) { Collection<V> values = data.get(key); if (values == null) return Collections.emptyList(); return values; } public Set<K> keySet() { return data.keySet(); } protected abstract void initializeStorage(); public boolean isEmpty() { for (Map.Entry<K, Collection<V>> pair: data.entrySet()) if (!pair.getValue().isEmpty()) return false; return true; } public boolean put(K key, V value) { Collection<V> values = data.get(key); if (values == null) { values = new HashSet<V>(); data.put(key, values); } values.add(value); return true; } public boolean remove(Object key, Object value) { Collection<V> values = data.get(key); if (values == null) return false; boolean result = values.remove(value); if (result && values.isEmpty()) { data.remove(key); } return result; } public Collection<V> removeAll(Object key) { Collection<V> values = data.remove(key); if (values == null) return Collections.emptyList(); return values; } public Collection<Collection<V>> valueCollections() { return data.values(); } }