1/*
2 * Copyright (C) 2013 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
15package com.google.common.collect;
16
17import static com.google.common.base.Preconditions.checkNotNull;
18
19import com.google.common.annotations.GwtCompatible;
20import com.google.common.base.Objects;
21import com.google.common.base.Predicate;
22import com.google.common.base.Predicates;
23
24import java.util.AbstractCollection;
25import java.util.Collection;
26import java.util.Iterator;
27import java.util.Map;
28import java.util.Map.Entry;
29
30import javax.annotation.Nullable;
31
32/**
33 * Implementation for {@link FilteredMultimap#values()}.
34 *
35 * @author Louis Wasserman
36 */
37@GwtCompatible
38final class FilteredMultimapValues<K, V> extends AbstractCollection<V> {
39  private final FilteredMultimap<K, V> multimap;
40
41  FilteredMultimapValues(FilteredMultimap<K, V> multimap) {
42    this.multimap = checkNotNull(multimap);
43  }
44
45  @Override
46  public Iterator<V> iterator() {
47    return Maps.valueIterator(multimap.entries().iterator());
48  }
49
50  @Override
51  public boolean contains(@Nullable Object o) {
52    return multimap.containsValue(o);
53  }
54
55  @Override
56  public int size() {
57    return multimap.size();
58  }
59
60  @Override
61  public boolean remove(@Nullable Object o) {
62    Predicate<? super Entry<K, V>> entryPredicate = multimap.entryPredicate();
63    for (Iterator<Entry<K, V>> unfilteredItr = multimap.unfiltered().entries().iterator();
64        unfilteredItr.hasNext();) {
65      Map.Entry<K, V> entry = unfilteredItr.next();
66      if (entryPredicate.apply(entry) && Objects.equal(entry.getValue(), o)) {
67        unfilteredItr.remove();
68        return true;
69      }
70    }
71    return false;
72  }
73
74  @Override
75  public boolean removeAll(Collection<?> c) {
76    return Iterables.removeIf(multimap.unfiltered().entries(),
77        // explicit <Entry<K, V>> is required to build with JDK6
78        Predicates.<Entry<K, V>>and(multimap.entryPredicate(),
79            Maps.<V>valuePredicateOnEntries(Predicates.in(c))));
80  }
81
82  @Override
83  public boolean retainAll(Collection<?> c) {
84    return Iterables.removeIf(multimap.unfiltered().entries(),
85        // explicit <Entry<K, V>> is required to build with JDK6
86        Predicates.<Entry<K, V>>and(multimap.entryPredicate(),
87            Maps.<V>valuePredicateOnEntries(Predicates.not(Predicates.in(c)))));
88  }
89
90  @Override
91  public void clear() {
92    multimap.clear();
93  }
94}
95