Coverage Summary for Class: FilteredKeyMultimap (com.google.common.collect)
| Class | Method, % | Line, % |
|---|---|---|
| FilteredKeyMultimap | 0% (0/15) | 0% (0/30) |
| FilteredKeyMultimap$AddRejectingList | 0% (0/6) | 0% (0/12) |
| FilteredKeyMultimap$AddRejectingSet | 0% (0/4) | 0% (0/6) |
| FilteredKeyMultimap$Entries | 0% (0/3) | 0% (0/8) |
| Total | 0% (0/28) | 0% (0/56) |
1 /* 2 * Copyright (C) 2012 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.common.collect; 16 17 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkPositionIndex; 19 20 import com.google.common.annotations.GwtCompatible; 21 import com.google.common.base.Predicate; 22 import com.google.errorprone.annotations.CanIgnoreReturnValue; 23 import com.google.j2objc.annotations.WeakOuter; 24 import java.util.Collection; 25 import java.util.Collections; 26 import java.util.Iterator; 27 import java.util.List; 28 import java.util.Map; 29 import java.util.Map.Entry; 30 import java.util.Set; 31 import org.checkerframework.checker.nullness.qual.Nullable; 32 33 /** 34 * Implementation of {@link Multimaps#filterKeys(Multimap, Predicate)}. 35 * 36 * @author Louis Wasserman 37 */ 38 @GwtCompatible 39 class FilteredKeyMultimap<K, V> extends AbstractMultimap<K, V> implements FilteredMultimap<K, V> { 40 final Multimap<K, V> unfiltered; 41 final Predicate<? super K> keyPredicate; 42 43 FilteredKeyMultimap(Multimap<K, V> unfiltered, Predicate<? super K> keyPredicate) { 44 this.unfiltered = checkNotNull(unfiltered); 45 this.keyPredicate = checkNotNull(keyPredicate); 46 } 47 48 @Override 49 public Multimap<K, V> unfiltered() { 50 return unfiltered; 51 } 52 53 @Override 54 public Predicate<? super Entry<K, V>> entryPredicate() { 55 return Maps.keyPredicateOnEntries(keyPredicate); 56 } 57 58 @Override 59 public int size() { 60 int size = 0; 61 for (Collection<V> collection : asMap().values()) { 62 size += collection.size(); 63 } 64 return size; 65 } 66 67 @Override 68 public boolean containsKey(@Nullable Object key) { 69 if (unfiltered.containsKey(key)) { 70 @SuppressWarnings("unchecked") // k is equal to a K, if not one itself 71 K k = (K) key; 72 return keyPredicate.apply(k); 73 } 74 return false; 75 } 76 77 @Override 78 public Collection<V> removeAll(Object key) { 79 return containsKey(key) ? unfiltered.removeAll(key) : unmodifiableEmptyCollection(); 80 } 81 82 Collection<V> unmodifiableEmptyCollection() { 83 if (unfiltered instanceof SetMultimap) { 84 return ImmutableSet.of(); 85 } else { 86 return ImmutableList.of(); 87 } 88 } 89 90 @Override 91 public void clear() { 92 keySet().clear(); 93 } 94 95 @Override 96 Set<K> createKeySet() { 97 return Sets.filter(unfiltered.keySet(), keyPredicate); 98 } 99 100 @Override 101 public Collection<V> get(K key) { 102 if (keyPredicate.apply(key)) { 103 return unfiltered.get(key); 104 } else if (unfiltered instanceof SetMultimap) { 105 return new AddRejectingSet<>(key); 106 } else { 107 return new AddRejectingList<>(key); 108 } 109 } 110 111 static class AddRejectingSet<K, V> extends ForwardingSet<V> { 112 final K key; 113 114 AddRejectingSet(K key) { 115 this.key = key; 116 } 117 118 @Override 119 public boolean add(V element) { 120 throw new IllegalArgumentException("Key does not satisfy predicate: " + key); 121 } 122 123 @Override 124 public boolean addAll(Collection<? extends V> collection) { 125 checkNotNull(collection); 126 throw new IllegalArgumentException("Key does not satisfy predicate: " + key); 127 } 128 129 @Override 130 protected Set<V> delegate() { 131 return Collections.emptySet(); 132 } 133 } 134 135 static class AddRejectingList<K, V> extends ForwardingList<V> { 136 final K key; 137 138 AddRejectingList(K key) { 139 this.key = key; 140 } 141 142 @Override 143 public boolean add(V v) { 144 add(0, v); 145 return true; 146 } 147 148 @Override 149 public void add(int index, V element) { 150 checkPositionIndex(index, 0); 151 throw new IllegalArgumentException("Key does not satisfy predicate: " + key); 152 } 153 154 @Override 155 public boolean addAll(Collection<? extends V> collection) { 156 addAll(0, collection); 157 return true; 158 } 159 160 @CanIgnoreReturnValue 161 @Override 162 public boolean addAll(int index, Collection<? extends V> elements) { 163 checkNotNull(elements); 164 checkPositionIndex(index, 0); 165 throw new IllegalArgumentException("Key does not satisfy predicate: " + key); 166 } 167 168 @Override 169 protected List<V> delegate() { 170 return Collections.emptyList(); 171 } 172 } 173 174 @Override 175 Iterator<Entry<K, V>> entryIterator() { 176 throw new AssertionError("should never be called"); 177 } 178 179 @Override 180 Collection<Entry<K, V>> createEntries() { 181 return new Entries(); 182 } 183 184 @WeakOuter 185 class Entries extends ForwardingCollection<Entry<K, V>> { 186 @Override 187 protected Collection<Entry<K, V>> delegate() { 188 return Collections2.filter(unfiltered.entries(), entryPredicate()); 189 } 190 191 @Override 192 @SuppressWarnings("unchecked") 193 public boolean remove(@Nullable Object o) { 194 if (o instanceof Entry) { 195 Entry<?, ?> entry = (Entry<?, ?>) o; 196 if (unfiltered.containsKey(entry.getKey()) 197 // if this holds, then we know entry.getKey() is a K 198 && keyPredicate.apply((K) entry.getKey())) { 199 return unfiltered.remove(entry.getKey(), entry.getValue()); 200 } 201 } 202 return false; 203 } 204 } 205 206 @Override 207 Collection<V> createValues() { 208 return new FilteredMultimapValues<>(this); 209 } 210 211 @Override 212 Map<K, Collection<V>> createAsMap() { 213 return Maps.filterKeys(unfiltered.asMap(), keyPredicate); 214 } 215 216 @Override 217 Multiset<K> createKeys() { 218 return Multisets.filter(unfiltered.keys(), keyPredicate); 219 } 220 }