]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/util/IdentityHashSet.java
Re-implement URIStringUtils escape and unescape using Unicode
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / util / IdentityHashSet.java
1 package org.simantics.databoard.util;
2
3 import java.util.AbstractSet;
4 import java.util.Collection;
5 import java.util.ConcurrentModificationException;
6 import java.util.IdentityHashMap;
7 import java.util.Iterator;
8 import java.util.Set;
9
10 public class IdentityHashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
11 {
12 static final long serialVersionUID = -5024744406713321676L;
13
14 private transient IdentityHashMap<E,Object> map;
15
16 // Dummy value to associate with an Object in the backing Map
17 private static final Object PRESENT = new Object();
18
19 /**
20  * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
21  * default initial capacity (16) and load factor (0.75).
22  */
23 public IdentityHashSet() {
24 map = new IdentityHashMap<E,Object>();
25 }
26
27 /**
28  * Constructs a new set containing the elements in the specified
29  * collection.  The <tt>HashMap</tt> is created with default load factor
30  * (0.75) and an initial capacity sufficient to contain the elements in
31  * the specified collection.
32  *
33  * @param c the collection whose elements are to be placed into this set
34  * @throws NullPointerException if the specified collection is null
35  */
36 public IdentityHashSet(Collection<? extends E> c) {
37 map = new IdentityHashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
38 addAll(c);
39 }
40
41
42 /**
43  * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
44  * the specified initial capacity and default load factor (0.75).
45  *
46  * @param      initialCapacity   the initial capacity of the hash table
47  * @throws     IllegalArgumentException if the initial capacity is less
48  *             than zero
49  */
50 public IdentityHashSet(int initialCapacity) {
51 map = new IdentityHashMap<E,Object>(initialCapacity);
52 }
53
54 /**
55  * Returns an iterator over the elements in this set.  The elements
56  * are returned in no particular order.
57  *
58  * @return an Iterator over the elements in this set
59  * @see ConcurrentModificationException
60  */
61 public Iterator<E> iterator() {
62 return map.keySet().iterator();
63 }
64
65 /**
66  * Returns the number of elements in this set (its cardinality).
67  *
68  * @return the number of elements in this set (its cardinality)
69  */
70 public int size() {
71 return map.size();
72 }
73
74 /**
75  * Returns <tt>true</tt> if this set contains no elements.
76  *
77  * @return <tt>true</tt> if this set contains no elements
78  */
79 public boolean isEmpty() {
80 return map.isEmpty();
81 }
82
83 /**
84  * Returns <tt>true</tt> if this set contains the specified element.
85  * More formally, returns <tt>true</tt> if and only if this set
86  * contains an element <tt>e</tt> such that
87  * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
88  *
89  * @param o element whose presence in this set is to be tested
90  * @return <tt>true</tt> if this set contains the specified element
91  */
92 public boolean contains(Object o) {
93 return map.containsKey(o);
94 }
95
96 /**
97  * Adds the specified element to this set if it is not already present.
98  * More formally, adds the specified element <tt>e</tt> to this set if
99  * this set contains no element <tt>e2</tt> such that
100  * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
101  * If this set already contains the element, the call leaves the set
102  * unchanged and returns <tt>false</tt>.
103  *
104  * @param e element to be added to this set
105  * @return <tt>true</tt> if this set did not already contain the specified
106  * element
107  */
108 public boolean add(E e) {
109 return map.put(e, PRESENT)==null;
110 }
111
112 /**
113  * Removes the specified element from this set if it is present.
114  * More formally, removes an element <tt>e</tt> such that
115  * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>,
116  * if this set contains such an element.  Returns <tt>true</tt> if
117  * this set contained the element (or equivalently, if this set
118  * changed as a result of the call).  (This set will not contain the
119  * element once the call returns.)
120  *
121  * @param o object to be removed from this set, if present
122  * @return <tt>true</tt> if the set contained the specified element
123  */
124 public boolean remove(Object o) {
125 return map.remove(o)==PRESENT;
126 }
127
128 /**
129  * Removes all of the elements from this set.
130  * The set will be empty after this call returns.
131  */
132 public void clear() {
133 map.clear();
134 }
135
136 /**
137  * Returns a shallow copy of this <tt>HashSet</tt> instance: the elements
138  * themselves are not cloned.
139  *
140  * @return a shallow copy of this set
141  */
142 @SuppressWarnings("unchecked")
143 public Object clone() {
144 try {
145         IdentityHashSet<E> newSet = (IdentityHashSet<E>) super.clone();
146     newSet.map = (IdentityHashMap<E, Object>) map.clone();
147     return newSet;
148 } catch (CloneNotSupportedException e) {
149     throw new InternalError();
150 }
151 }
152
153 /**
154  * Save the state of this <tt>HashSet</tt> instance to a stream (that is,
155  * serialize it).
156  *
157  * @serialData The capacity of the backing <tt>HashMap</tt> instance
158  *                 (int), and its load factor (float) are emitted, followed by
159  *                 the size of the set (the number of elements it contains)
160  *                 (int), followed by all of its elements (each an Object) in
161  *             no particular order.
162  */
163 private void writeObject(java.io.ObjectOutputStream s)
164     throws java.io.IOException {
165 // Write out any hidden serialization magic
166 s.defaultWriteObject();
167
168     // Write out size
169     s.writeInt(map.size());
170
171 // Write out all elements in the proper order.
172 for (Iterator<E> i=map.keySet().iterator(); i.hasNext(); )
173         s.writeObject(i.next());
174 }
175
176 /**
177  * Reconstitute the <tt>HashSet</tt> instance from a stream (that is,
178  * deserialize it).
179  */
180 @SuppressWarnings("unchecked")
181 private void readObject(java.io.ObjectInputStream s)
182     throws java.io.IOException, ClassNotFoundException {
183 // Read in any hidden serialization magic
184 s.defaultReadObject();
185
186 //      Read in size
187         int size = s.readInt();
188
189     // Read in HashMap capacity and load factor and create backing HashMap
190     map = new IdentityHashMap<E,Object>(size);
191
192
193 // Read in all elements in the proper order.
194 for (int i=0; i<size; i++) {
195         E e = (E) s.readObject();
196         map.put(e, PRESENT);
197     }
198 }
199 }
200