001 /*--------------------------------------------------------------------------+
002 $Id: IdentityHashSet.java 26283 2010-02-18 11:18:57Z juergens $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | 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, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.collections;
019
020 import java.util.AbstractSet;
021 import java.util.Collection;
022 import java.util.IdentityHashMap;
023 import java.util.Iterator;
024
025 /**
026 * This class implements a set based on referential equality similar to JDK
027 * class {@link IdentityHashMap}. This class can be e.g. used to implement
028 * listener lists that should not rely on the listeners <code>equals()</code>-methods.
029 * <p>
030 * The implementation is based on class {@link java.util.HashSet} that also uses
031 * an underlying hash map.
032 *
033 *
034 * @author Florian Deissenboeck
035 * @author $Author: juergens $
036 * @version $Rev: 26283 $
037 * @levd.rating GREEN Hash: A3753EB461A1466EFCA699DCE847468B
038 */
039 public class IdentityHashSet<E> extends AbstractSet<E> {
040
041 /** Dummy object for the map. */
042 private static final Object PRESENT = new Object();
043
044 /** The map that actually stores the values. */
045 private final IdentityHashMap<E, Object> map;
046
047 /** Create new identity hash set. */
048 public IdentityHashSet() {
049 map = new IdentityHashMap<E, Object>();
050 }
051
052 /** Create new identity hash set from an existing collection. */
053 public IdentityHashSet(Collection<? extends E> collection) {
054 this(collection.size());
055
056 for (E e : collection) {
057 add(e);
058 }
059 }
060
061 /** Create new identity hash set with an expected maximum size. */
062 public IdentityHashSet(int expectedMaxSize) {
063 map = new IdentityHashMap<E, Object>(expectedMaxSize);
064 }
065
066 /**
067 * Adds the specified element to this set if it is not already present.
068 *
069 * @param o
070 * element to be added to this set.
071 * @return <tt>true</tt> if the set did not already contain the specified
072 * element.
073 */
074 @Override
075 public boolean add(E o) {
076 return map.put(o, PRESENT) == null;
077 }
078
079 /**
080 * Removes all of the elements from this set.
081 */
082 @Override
083 public void clear() {
084 map.clear();
085 }
086
087 /**
088 * Returns a shallow copy of this <tt>IdentityHashSet</tt> instance: the
089 * elements themselves are not cloned.
090 *
091 * @return a shallow copy of this set.
092 */
093 @Override
094 public IdentityHashSet<E> clone() {
095 return new IdentityHashSet<E>(this);
096 }
097
098 /**
099 * Returns <tt>true</tt> if this set contains the specified element.
100 *
101 * @param o
102 * element whose presence in this set is to be tested.
103 * @return <tt>true</tt> if this set contains the specified element.
104 */
105 @Override
106 public boolean contains(Object o) {
107 return map.containsKey(o);
108 }
109
110 /**
111 * Returns <tt>true</tt> if this set contains no elements.
112 *
113 * @return <tt>true</tt> if this set contains no elements.
114 */
115 @Override
116 public boolean isEmpty() {
117 return map.isEmpty();
118 }
119
120 /** Return iterator over the set. */
121 @Override
122 public Iterator<E> iterator() {
123 return map.keySet().iterator();
124 }
125
126 /**
127 * Removes the specified element from this set if it is present.
128 *
129 * @param o
130 * object to be removed from this set, if present.
131 * @return <tt>true</tt> if the set contained the specified element.
132 */
133 @Override
134 public boolean remove(Object o) {
135 return map.remove(o) == PRESENT;
136 }
137
138 /**
139 * Get set size.
140 */
141 @Override
142 public int size() {
143 return map.size();
144 }
145
146 }