001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2002 Ondrej Lhotak
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: package soot.util;
021:
022: import java.util.*;
023:
024: /** A map with sets as values, HashMap implementation.
025: *
026: * @author Ondrej Lhotak
027: */
028:
029: public class HashMultiMap implements MultiMap {
030: Map<Object, Set> m = new HashMap<Object, Set>(0);
031:
032: public HashMultiMap() {
033: }
034:
035: public HashMultiMap(MultiMap m) {
036: putAll(m);
037: }
038:
039: public void putAll(MultiMap m) {
040: Iterator it = m.keySet().iterator();
041: while (it.hasNext()) {
042: Object o = it.next();
043: putAll(o, m.get(o));
044: }
045: }
046:
047: public boolean isEmpty() {
048: return numKeys() == 0;
049: }
050:
051: public int numKeys() {
052: return m.size();
053: }
054:
055: public boolean containsKey(Object key) {
056: return m.containsKey(key);
057: }
058:
059: public boolean containsValue(Object value) {
060: Iterator<Set> it = m.values().iterator();
061: while (it.hasNext()) {
062: Set s = it.next();
063: if (s.contains(value))
064: return true;
065: }
066: return false;
067: }
068:
069: protected Set newSet() {
070: return new HashSet(4);
071: }
072:
073: private Set findSet(Object key) {
074: Set s = m.get(key);
075: if (s == null) {
076: s = newSet();
077: m.put(key, s);
078: }
079: return s;
080: }
081:
082: public boolean put(Object key, Object value) {
083: return findSet(key).add(value);
084: }
085:
086: public boolean putAll(Object key, Set values) {
087: if (values.isEmpty())
088: return false;
089: return findSet(key).addAll(values);
090: }
091:
092: public boolean remove(Object key, Object value) {
093: Set s = m.get(key);
094: if (s == null)
095: return false;
096: boolean ret = s.remove(value);
097: if (s.isEmpty()) {
098: m.remove(key);
099: }
100: return ret;
101: }
102:
103: public boolean remove(Object key) {
104: return null != m.remove(key);
105: }
106:
107: public boolean removeAll(Object key, Set values) {
108: Set s = m.get(key);
109: if (s == null)
110: return false;
111: boolean ret = s.removeAll(values);
112: if (s.isEmpty()) {
113: m.remove(key);
114: }
115: return ret;
116: }
117:
118: public Set get(Object o) {
119: Set ret = m.get(o);
120: if (ret == null)
121: return Collections.EMPTY_SET;
122: return Collections.unmodifiableSet(ret);
123: }
124:
125: public Set keySet() {
126: return m.keySet();
127: }
128:
129: public Set values() {
130: Set ret = new HashSet(0);
131: Iterator<Set> it = m.values().iterator();
132: while (it.hasNext()) {
133: Set s = it.next();
134: ret.addAll(s);
135: }
136: return ret;
137: }
138:
139: public boolean equals(Object o) {
140: if (!(o instanceof MultiMap))
141: return false;
142: MultiMap mm = (MultiMap) o;
143: if (!keySet().equals(mm.keySet()))
144: return false;
145: Iterator it = m.entrySet().iterator();
146: while (it.hasNext()) {
147: Map.Entry e = (Map.Entry) it.next();
148: Set s = (Set) e.getValue();
149: if (!s.equals(mm.get(e.getKey())))
150: return false;
151: }
152: return true;
153: }
154:
155: public int hashCode() {
156: return m.hashCode();
157: }
158: }
|