17dd252788645e940eada959bdde927426e2531c9Paul Duffin/* 27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2012 The Guava Authors 37dd252788645e940eada959bdde927426e2531c9Paul Duffin * 40888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 50888a09821a98ac0680fad765217302858e70fa4Paul Duffin * in compliance with the License. You may obtain a copy of the License at 67dd252788645e940eada959bdde927426e2531c9Paul Duffin * 77dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 87dd252788645e940eada959bdde927426e2531c9Paul Duffin * 90888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Unless required by applicable law or agreed to in writing, software distributed under the License 100888a09821a98ac0680fad765217302858e70fa4Paul Duffin * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 110888a09821a98ac0680fad765217302858e70fa4Paul Duffin * or implied. See the License for the specific language governing permissions and limitations under 120888a09821a98ac0680fad765217302858e70fa4Paul Duffin * the License. 137dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 147dd252788645e940eada959bdde927426e2531c9Paul Duffin 157dd252788645e940eada959bdde927426e2531c9Paul Duffinpackage com.google.common.collect; 167dd252788645e940eada959bdde927426e2531c9Paul Duffin 177dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull; 187dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkPositionIndex; 197dd252788645e940eada959bdde927426e2531c9Paul Duffin 207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtCompatible; 217dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Predicate; 227dd252788645e940eada959bdde927426e2531c9Paul Duffin 237dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collection; 247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collections; 257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Iterator; 267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.List; 277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map; 287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map.Entry; 297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Set; 307dd252788645e940eada959bdde927426e2531c9Paul Duffin 317dd252788645e940eada959bdde927426e2531c9Paul Duffinimport javax.annotation.Nullable; 327dd252788645e940eada959bdde927426e2531c9Paul Duffin 337dd252788645e940eada959bdde927426e2531c9Paul Duffin/** 347dd252788645e940eada959bdde927426e2531c9Paul Duffin * Implementation of {@link Multimaps#filterKeys(Multimap, Predicate)}. 357dd252788645e940eada959bdde927426e2531c9Paul Duffin * 367dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Louis Wasserman 377dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 387dd252788645e940eada959bdde927426e2531c9Paul Duffin@GwtCompatible 390888a09821a98ac0680fad765217302858e70fa4Paul Duffinclass FilteredKeyMultimap<K, V> extends AbstractMultimap<K, V> implements FilteredMultimap<K, V> { 400888a09821a98ac0680fad765217302858e70fa4Paul Duffin final Multimap<K, V> unfiltered; 417dd252788645e940eada959bdde927426e2531c9Paul Duffin final Predicate<? super K> keyPredicate; 427dd252788645e940eada959bdde927426e2531c9Paul Duffin 437dd252788645e940eada959bdde927426e2531c9Paul Duffin FilteredKeyMultimap(Multimap<K, V> unfiltered, Predicate<? super K> keyPredicate) { 440888a09821a98ac0680fad765217302858e70fa4Paul Duffin this.unfiltered = checkNotNull(unfiltered); 457dd252788645e940eada959bdde927426e2531c9Paul Duffin this.keyPredicate = checkNotNull(keyPredicate); 467dd252788645e940eada959bdde927426e2531c9Paul Duffin } 477dd252788645e940eada959bdde927426e2531c9Paul Duffin 487dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 490888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Multimap<K, V> unfiltered() { 500888a09821a98ac0680fad765217302858e70fa4Paul Duffin return unfiltered; 517dd252788645e940eada959bdde927426e2531c9Paul Duffin } 527dd252788645e940eada959bdde927426e2531c9Paul Duffin 530888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 540888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Predicate<? super Entry<K, V>> entryPredicate() { 550888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Maps.keyPredicateOnEntries(keyPredicate); 560888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 570888a09821a98ac0680fad765217302858e70fa4Paul Duffin 580888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 597dd252788645e940eada959bdde927426e2531c9Paul Duffin public int size() { 607dd252788645e940eada959bdde927426e2531c9Paul Duffin int size = 0; 617dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Collection<V> collection : asMap().values()) { 627dd252788645e940eada959bdde927426e2531c9Paul Duffin size += collection.size(); 637dd252788645e940eada959bdde927426e2531c9Paul Duffin } 647dd252788645e940eada959bdde927426e2531c9Paul Duffin return size; 657dd252788645e940eada959bdde927426e2531c9Paul Duffin } 667dd252788645e940eada959bdde927426e2531c9Paul Duffin 670888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 687dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean containsKey(@Nullable Object key) { 697dd252788645e940eada959bdde927426e2531c9Paul Duffin if (unfiltered.containsKey(key)) { 700888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // k is equal to a K, if not one itself 717dd252788645e940eada959bdde927426e2531c9Paul Duffin K k = (K) key; 727dd252788645e940eada959bdde927426e2531c9Paul Duffin return keyPredicate.apply(k); 737dd252788645e940eada959bdde927426e2531c9Paul Duffin } 747dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 757dd252788645e940eada959bdde927426e2531c9Paul Duffin } 767dd252788645e940eada959bdde927426e2531c9Paul Duffin 770888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 787dd252788645e940eada959bdde927426e2531c9Paul Duffin public Collection<V> removeAll(Object key) { 797dd252788645e940eada959bdde927426e2531c9Paul Duffin return containsKey(key) ? unfiltered.removeAll(key) : unmodifiableEmptyCollection(); 807dd252788645e940eada959bdde927426e2531c9Paul Duffin } 817dd252788645e940eada959bdde927426e2531c9Paul Duffin 827dd252788645e940eada959bdde927426e2531c9Paul Duffin Collection<V> unmodifiableEmptyCollection() { 837dd252788645e940eada959bdde927426e2531c9Paul Duffin if (unfiltered instanceof SetMultimap) { 847dd252788645e940eada959bdde927426e2531c9Paul Duffin return ImmutableSet.of(); 857dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 867dd252788645e940eada959bdde927426e2531c9Paul Duffin return ImmutableList.of(); 877dd252788645e940eada959bdde927426e2531c9Paul Duffin } 887dd252788645e940eada959bdde927426e2531c9Paul Duffin } 897dd252788645e940eada959bdde927426e2531c9Paul Duffin 900888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 917dd252788645e940eada959bdde927426e2531c9Paul Duffin public void clear() { 927dd252788645e940eada959bdde927426e2531c9Paul Duffin keySet().clear(); 937dd252788645e940eada959bdde927426e2531c9Paul Duffin } 947dd252788645e940eada959bdde927426e2531c9Paul Duffin 957dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 967dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<K> createKeySet() { 977dd252788645e940eada959bdde927426e2531c9Paul Duffin return Sets.filter(unfiltered.keySet(), keyPredicate); 987dd252788645e940eada959bdde927426e2531c9Paul Duffin } 997dd252788645e940eada959bdde927426e2531c9Paul Duffin 1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 1017dd252788645e940eada959bdde927426e2531c9Paul Duffin public Collection<V> get(K key) { 1027dd252788645e940eada959bdde927426e2531c9Paul Duffin if (keyPredicate.apply(key)) { 1037dd252788645e940eada959bdde927426e2531c9Paul Duffin return unfiltered.get(key); 1047dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (unfiltered instanceof SetMultimap) { 1057dd252788645e940eada959bdde927426e2531c9Paul Duffin return new AddRejectingSet<K, V>(key); 1067dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 1077dd252788645e940eada959bdde927426e2531c9Paul Duffin return new AddRejectingList<K, V>(key); 1087dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1097dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1107dd252788645e940eada959bdde927426e2531c9Paul Duffin 1117dd252788645e940eada959bdde927426e2531c9Paul Duffin static class AddRejectingSet<K, V> extends ForwardingSet<V> { 1127dd252788645e940eada959bdde927426e2531c9Paul Duffin final K key; 1137dd252788645e940eada959bdde927426e2531c9Paul Duffin 1147dd252788645e940eada959bdde927426e2531c9Paul Duffin AddRejectingSet(K key) { 1157dd252788645e940eada959bdde927426e2531c9Paul Duffin this.key = key; 1167dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1177dd252788645e940eada959bdde927426e2531c9Paul Duffin 1187dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1197dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean add(V element) { 1207dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new IllegalArgumentException("Key does not satisfy predicate: " + key); 1217dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1227dd252788645e940eada959bdde927426e2531c9Paul Duffin 1237dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1247dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean addAll(Collection<? extends V> collection) { 1257dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(collection); 1267dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new IllegalArgumentException("Key does not satisfy predicate: " + key); 1277dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1287dd252788645e940eada959bdde927426e2531c9Paul Duffin 1297dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1307dd252788645e940eada959bdde927426e2531c9Paul Duffin protected Set<V> delegate() { 1317dd252788645e940eada959bdde927426e2531c9Paul Duffin return Collections.emptySet(); 1327dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1337dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1347dd252788645e940eada959bdde927426e2531c9Paul Duffin 1357dd252788645e940eada959bdde927426e2531c9Paul Duffin static class AddRejectingList<K, V> extends ForwardingList<V> { 1367dd252788645e940eada959bdde927426e2531c9Paul Duffin final K key; 1377dd252788645e940eada959bdde927426e2531c9Paul Duffin 1387dd252788645e940eada959bdde927426e2531c9Paul Duffin AddRejectingList(K key) { 1397dd252788645e940eada959bdde927426e2531c9Paul Duffin this.key = key; 1407dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1417dd252788645e940eada959bdde927426e2531c9Paul Duffin 1427dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1437dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean add(V v) { 1447dd252788645e940eada959bdde927426e2531c9Paul Duffin add(0, v); 1457dd252788645e940eada959bdde927426e2531c9Paul Duffin return true; 1467dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1477dd252788645e940eada959bdde927426e2531c9Paul Duffin 1487dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1497dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean addAll(Collection<? extends V> collection) { 1507dd252788645e940eada959bdde927426e2531c9Paul Duffin addAll(0, collection); 1517dd252788645e940eada959bdde927426e2531c9Paul Duffin return true; 1527dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1537dd252788645e940eada959bdde927426e2531c9Paul Duffin 1547dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1557dd252788645e940eada959bdde927426e2531c9Paul Duffin public void add(int index, V element) { 1567dd252788645e940eada959bdde927426e2531c9Paul Duffin checkPositionIndex(index, 0); 1577dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new IllegalArgumentException("Key does not satisfy predicate: " + key); 1587dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1597dd252788645e940eada959bdde927426e2531c9Paul Duffin 1607dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1617dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean addAll(int index, Collection<? extends V> elements) { 1627dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(elements); 1637dd252788645e940eada959bdde927426e2531c9Paul Duffin checkPositionIndex(index, 0); 1647dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new IllegalArgumentException("Key does not satisfy predicate: " + key); 1657dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1667dd252788645e940eada959bdde927426e2531c9Paul Duffin 1677dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1687dd252788645e940eada959bdde927426e2531c9Paul Duffin protected List<V> delegate() { 1697dd252788645e940eada959bdde927426e2531c9Paul Duffin return Collections.emptyList(); 1707dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1717dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1727dd252788645e940eada959bdde927426e2531c9Paul Duffin 1737dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1747dd252788645e940eada959bdde927426e2531c9Paul Duffin Iterator<Entry<K, V>> entryIterator() { 1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new AssertionError("should never be called"); 1767dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1777dd252788645e940eada959bdde927426e2531c9Paul Duffin 1787dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1797dd252788645e940eada959bdde927426e2531c9Paul Duffin Collection<Entry<K, V>> createEntries() { 1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new Entries(); 1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1827dd252788645e940eada959bdde927426e2531c9Paul Duffin 1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin class Entries extends ForwardingCollection<Entry<K, V>> { 1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin protected Collection<Entry<K, V>> delegate() { 1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Collections2.filter(unfiltered.entries(), entryPredicate()); 1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1887dd252788645e940eada959bdde927426e2531c9Paul Duffin 1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") 1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin public boolean remove(@Nullable Object o) { 1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (o instanceof Entry) { 1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin Entry<?, ?> entry = (Entry<?, ?>) o; 1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (unfiltered.containsKey(entry.getKey()) 1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin // if this holds, then we know entry.getKey() is a K 1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin && keyPredicate.apply((K) entry.getKey())) { 1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin return unfiltered.remove(entry.getKey(), entry.getValue()); 1987dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1997dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin return false; 2010888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2050888a09821a98ac0680fad765217302858e70fa4Paul Duffin Collection<V> createValues() { 2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new FilteredMultimapValues<K, V>(this); 2077dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2087dd252788645e940eada959bdde927426e2531c9Paul Duffin 2097dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 2107dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, Collection<V>> createAsMap() { 2117dd252788645e940eada959bdde927426e2531c9Paul Duffin return Maps.filterKeys(unfiltered.asMap(), keyPredicate); 2127dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2137dd252788645e940eada959bdde927426e2531c9Paul Duffin 2147dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 2157dd252788645e940eada959bdde927426e2531c9Paul Duffin Multiset<K> createKeys() { 2167dd252788645e940eada959bdde927426e2531c9Paul Duffin return Multisets.filter(unfiltered.keys(), keyPredicate); 2177dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2187dd252788645e940eada959bdde927426e2531c9Paul Duffin} 219