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(final Map<K, Set<V>> map) {
029    this.map = map;
030  }
031
032  public void put(final K key, final 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(final K key) {
047    final 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(final K key, final V v) {
056    final 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(final Entry<K, V> e) {
065    put(e.getKey(), e.getValue());
066    return true;
067  }
068
069  @Override
070  public boolean addAll(final Collection<? extends Entry<K, V>> c) {
071    boolean ret = false;
072    for (final 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(final Object o) {
087    final Entry<?, ?> e = (Entry<?, ?>) o;
088    return contains((K) e.getKey(), (V) e.getValue());
089  }
090
091  @Override
092  public boolean containsAll(final Collection<?> c) {
093    for (final 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      private Iterator<V> cur;
111      private 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 && it.hasNext()) {
121          final Entry<K, Set<V>> e = it.next();
122          curKey = e.getKey();
123          cur = e.getValue().iterator();
124        }
125        final K k = curKey;
126        final V v = cur.next();
127        if (!cur.hasNext()) {
128          cur = null;
129        }
130
131        return new Entry<K, V>() {
132
133          @Override
134          public K getKey() {
135            return k;
136          }
137
138          @Override
139          public V getValue() {
140            return v;
141          }
142
143          @Override
144          public V setValue(final V value) {
145            throw new UnsupportedOperationException();
146          }
147
148        };
149      }
150
151      @Override
152      public void remove() {
153        throw new UnsupportedOperationException();
154      }
155
156    };
157  }
158
159  public Set<V> values() {
160    final Set<V> s = new HashSet<>();
161    for (final Entry<K, V> e : this) {
162      s.add(e.getValue());
163    }
164    return s;
165  }
166
167  @Override
168  public boolean remove(final Object o) {
169    throw new UnsupportedOperationException("MonotonicMultiMap does not support non-monotonic method remove!");
170  }
171
172  @Override
173  public boolean removeAll(final Collection<?> c) {
174    throw new UnsupportedOperationException("MonotonicMultiMap does not support non-monotonic method removeAll!");
175  }
176
177  @Override
178  public boolean retainAll(final Collection<?> c) {
179    throw new UnsupportedOperationException("MonotonicMultiMap does not support non-monotonic method retainAll!");
180  }
181
182  @Override
183  public int size() {
184    return size;
185  }
186
187  @Override
188  public Entry<K, V>[] toArray() {
189    throw new UnsupportedOperationException("No toArray() for MonotonicMulitMap (yet)");
190  }
191
192  @Override
193  public <T> T[] toArray(final T[] a) {
194    throw new UnsupportedOperationException("No toArray() for MonotonicMulitMap (yet)");
195  }
196
197  public boolean containsKey(final K k) {
198    if (map.containsKey(k)) {
199      return !getValuesForKey(k).isEmpty();
200    } else {
201      return false;
202    }
203  }
204}