This project has retired. For details please refer to its Attic page.
Source code
001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.reef.tang.util;
020
021import java.util.*;
022import java.util.Map.Entry;
023
024public abstract class AbstractMonotonicMultiMap<K, V> implements Collection<Entry<K, V>> {
025  protected Map<K, Set<V>> map;
026  private int size = 0;
027
028  public AbstractMonotonicMultiMap(Map<K, Set<V>> map) {
029    this.map = map;
030  }
031
032  public void put(K key, V v) {
033    Set<V> vals = map.get(key);
034    if (vals == null) {
035      vals = new MonotonicHashSet<V>();
036      map.put(key, vals);
037    }
038    vals.add(v);
039    size++;
040  }
041
042  public Set<K> keySet() {
043    return map.keySet();
044  }
045
046  public Set<V> getValuesForKey(K key) {
047    Set<V> ret = map.get(key);
048    if (ret == null) {
049      return new MonotonicHashSet<V>();
050    } else {
051      return ret;
052    }
053  }
054
055  public boolean contains(K key, V v) {
056    Set<V> vals = map.get(key);
057    if (vals != null) {
058      return vals.contains(v);
059    }
060    return false;
061  }
062
063  @Override
064  public boolean add(Entry<K, V> e) {
065    put(e.getKey(), e.getValue());
066    return true;
067  }
068
069  @Override
070  public boolean addAll(Collection<? extends Entry<K, V>> c) {
071    boolean ret = false;
072    for (Entry<K, V> e : c) {
073      add(e);
074      ret = true;
075    }
076    return ret;
077  }
078
079  @Override
080  public void clear() {
081    throw new UnsupportedOperationException("MonotonicMultiMap cannot be cleared!");
082  }
083
084  @SuppressWarnings("unchecked")
085  @Override
086  public boolean contains(Object o) {
087    Entry<?, ?> e = (Entry<?, ?>) o;
088    return contains((K) e.getKey(), (V) e.getValue());
089  }
090
091  @Override
092  public boolean containsAll(Collection<?> c) {
093    for (Object o : c) {
094      if (!contains(o)) {
095        return false;
096      }
097    }
098    return true;
099  }
100
101  @Override
102  public boolean isEmpty() {
103    return size == 0;
104  }
105
106  @Override
107  public Iterator<Entry<K, V>> iterator() {
108    final Iterator<Entry<K, Set<V>>> it = map.entrySet().iterator();
109    return new Iterator<Entry<K, V>>() {
110      Iterator<V> cur;
111      K curKey;
112
113      @Override
114      public boolean hasNext() {
115        return it.hasNext() || (cur != null && cur.hasNext());
116      }
117
118      @Override
119      public Entry<K, V> next() {
120        if (cur == null) {
121          if (it.hasNext()) {
122            Entry<K, Set<V>> e = it.next();
123            curKey = e.getKey();
124            cur = e.getValue().iterator();
125          }
126        }
127        final K k = curKey;
128        final V v = cur.next();
129        if (!cur.hasNext()) {
130          cur = null;
131        }
132
133        return new Entry<K, V>() {
134
135          @Override
136          public K getKey() {
137            return k;
138          }
139
140          @Override
141          public V getValue() {
142            return v;
143          }
144
145          @Override
146          public V setValue(V value) {
147            throw new UnsupportedOperationException();
148          }
149
150        };
151      }
152
153      @Override
154      public void remove() {
155        throw new UnsupportedOperationException();
156      }
157
158    };
159  }
160
161  public Set<V> values() {
162    Set<V> s = new HashSet<>();
163    for (Entry<K, V> e : this) {
164      s.add(e.getValue());
165    }
166    return s;
167  }
168
169  @Override
170  public boolean remove(Object o) {
171    throw new UnsupportedOperationException("MonotonicMultiMap does not support non-monotonic method remove!");
172  }
173
174  @Override
175  public boolean removeAll(Collection<?> c) {
176    throw new UnsupportedOperationException("MonotonicMultiMap does not support non-monotonic method removeAll!");
177  }
178
179  @Override
180  public boolean retainAll(Collection<?> c) {
181    throw new UnsupportedOperationException("MonotonicMultiMap does not support non-monotonic method retainAll!");
182  }
183
184  @Override
185  public int size() {
186    return size;
187  }
188
189  @Override
190  public Entry<K, V>[] toArray() {
191    throw new UnsupportedOperationException("No toArray() for MonotonicMulitMap (yet)");
192  }
193
194  @Override
195  public <T> T[] toArray(T[] a) {
196    throw new UnsupportedOperationException("No toArray() for MonotonicMulitMap (yet)");
197  }
198
199  public boolean containsKey(K k) {
200    if (map.containsKey(k)) {
201      return !getValuesForKey(k).isEmpty();
202    } else {
203      return false;
204    }
205  }
206}