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 }