001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.collections.set;
018
019 import java.io.Serializable;
020 import java.util.Collection;
021 import java.util.Iterator;
022 import java.util.Map;
023 import java.util.Set;
024
025 /**
026 * Decorates a <code>Map</code> to obtain <code>Set</code> behaviour.
027 * <p>
028 * This class is used to create a <code>Set</code> with the same properties as
029 * the key set of any map. Thus, a ReferenceSet can be created by wrapping a
030 * <code>ReferenceMap</code> in an instance of this class.
031 * <p>
032 * Most map implementation can be used to create a set by passing in dummy values.
033 * Exceptions include <code>BidiMap</code> implementations, as they require unique values.
034 *
035 * @since Commons Collections 3.1
036 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
037 *
038 * @author Stephen Colebourne
039 */
040 public final class MapBackedSet implements Set, Serializable {
041
042 /** Serialization version */
043 private static final long serialVersionUID = 6723912213766056587L;
044
045 /** The map being used as the backing store */
046 protected final Map map;
047 /** The dummyValue to use */
048 protected final Object dummyValue;
049
050 /**
051 * Factory method to create a set from a map.
052 *
053 * @param map the map to decorate, must not be null
054 * @throws IllegalArgumentException if set is null
055 */
056 public static Set decorate(Map map) {
057 return decorate(map, null);
058 }
059
060 /**
061 * Factory method to create a set from a map.
062 *
063 * @param map the map to decorate, must not be null
064 * @param dummyValue the dummy value to use
065 * @throws IllegalArgumentException if map is null
066 */
067 public static Set decorate(Map map, Object dummyValue) {
068 if (map == null) {
069 throw new IllegalArgumentException("The map must not be null");
070 }
071 return new MapBackedSet(map, dummyValue);
072 }
073
074 //-----------------------------------------------------------------------
075 /**
076 * Constructor that wraps (not copies).
077 *
078 * @param map the map to decorate, must not be null
079 * @param dummyValue the dummy value to use
080 * @throws IllegalArgumentException if map is null
081 */
082 private MapBackedSet(Map map, Object dummyValue) {
083 super();
084 this.map = map;
085 this.dummyValue = dummyValue;
086 }
087
088 //-----------------------------------------------------------------------
089 public int size() {
090 return map.size();
091 }
092
093 public boolean isEmpty() {
094 return map.isEmpty();
095 }
096
097 public Iterator iterator() {
098 return map.keySet().iterator();
099 }
100
101 public boolean contains(Object obj) {
102 return map.containsKey(obj);
103 }
104
105 public boolean containsAll(Collection coll) {
106 return map.keySet().containsAll(coll);
107 }
108
109 public boolean add(Object obj) {
110 int size = map.size();
111 map.put(obj, dummyValue);
112 return (map.size() != size);
113 }
114
115 public boolean addAll(Collection coll) {
116 int size = map.size();
117 for (Iterator it = coll.iterator(); it.hasNext();) {
118 Object obj = it.next();
119 map.put(obj, dummyValue);
120 }
121 return (map.size() != size);
122 }
123
124 public boolean remove(Object obj) {
125 int size = map.size();
126 map.remove(obj);
127 return (map.size() != size);
128 }
129
130 public boolean removeAll(Collection coll) {
131 return map.keySet().removeAll(coll);
132 }
133
134 public boolean retainAll(Collection coll) {
135 return map.keySet().retainAll(coll);
136 }
137
138 public void clear() {
139 map.clear();
140 }
141
142 public Object[] toArray() {
143 return map.keySet().toArray();
144 }
145
146 public Object[] toArray(Object[] array) {
147 return map.keySet().toArray(array);
148 }
149
150 public boolean equals(Object obj) {
151 return map.keySet().equals(obj);
152 }
153
154 public int hashCode() {
155 return map.keySet().hashCode();
156 }
157
158 }