11package org .python .util ;
22
3+ import java .io .IOException ;
4+ import java .io .ObjectInputStream ;
5+ import java .io .Serializable ;
6+ import java .util .AbstractSet ;
37import java .util .ArrayList ;
8+ import java .util .Collection ;
49import java .util .HashMap ;
510import java .util .HashSet ;
11+ import java .util .Iterator ;
612import java .util .List ;
713import java .util .Map ;
814import java .util .Set ;
915import java .util .concurrent .ConcurrentHashMap ;
1016import java .util .concurrent .ConcurrentMap ;
1117
12- import org .python .core .util .ConcurrentHashSet ;
13-
1418/**
1519 * Static methods to make instances of collections with their generic types inferred from what
1620 * they're being assigned to. The idea is stolen from <code>Sets</code>, <code>Lists</code> and
@@ -64,8 +68,8 @@ public static <K, V> ConcurrentMap<K, V> concurrentMap() {
6468 /**
6569 * Makes a Set using the generic type inferred from whatever this is being assigned to.
6670 */
67- public static <T > Set <T > set () {
68- return new HashSet <T >();
71+ public static <E > Set <E > set () {
72+ return new HashSet <E >();
6973 }
7074
7175 /**
@@ -84,8 +88,128 @@ public static <T, U extends T> Set<T> set(U...contents) {
8488 * Makes a Set, ensuring safe concurrent operations, using generic types inferred from
8589 * whatever this is being assigned to.
8690 */
87- public static <T > Set <T > concurrentSet () {
88- return new ConcurrentHashSet <T >(CHM_INITIAL_CAPACITY , CHM_LOAD_FACTOR ,
89- CHM_CONCURRENCY_LEVEL );
91+ public static <E > Set <E > concurrentSet () {
92+ return newSetFromMap (new ConcurrentHashMap <E , Boolean >(CHM_INITIAL_CAPACITY ,
93+ CHM_LOAD_FACTOR ,
94+ CHM_CONCURRENCY_LEVEL ));
95+ }
96+
97+ /**
98+ * Return a Set backed by the specified Map with the same ordering, concurrency and
99+ * performance characteristics.
100+ *
101+ * The specified Map must be empty at the time this method is invoked.
102+ *
103+ * Note that this method is based on Java 6's Collections.newSetFromMap, and will be
104+ * removed in a future version of Jython (likely 2.6) that will rely on Java 6.
105+ *
106+ * @param map the backing Map
107+ * @return a Set backed by the Map
108+ * @throws IllegalArgumentException if Map is not empty
109+ */
110+ public static <E > Set <E > newSetFromMap (Map <E , Boolean > map ) {
111+ return new SetFromMap <E >(map );
112+ }
113+
114+ /**
115+ * A Set backed by a generic Map.
116+ */
117+ private static class SetFromMap <E > extends AbstractSet <E >
118+ implements Serializable {
119+
120+ /** The backing Map. */
121+ private final Map <E , Boolean > map ;
122+
123+ /** Backing's KeySet. */
124+ private transient Set <E > keySet ;
125+
126+ public SetFromMap (Map <E , Boolean > map ) {
127+ if (!map .isEmpty ()) {
128+ throw new IllegalArgumentException ("Map is non-empty" );
129+ }
130+ this .map = map ;
131+ keySet = map .keySet ();
132+ }
133+
134+ @ Override
135+ public int size () {
136+ return map .size ();
137+ }
138+
139+ @ Override
140+ public boolean isEmpty () {
141+ return map .isEmpty ();
142+ }
143+
144+ @ Override
145+ public boolean contains (Object o ) {
146+ return map .containsKey (o );
147+ }
148+
149+ @ Override
150+ public boolean containsAll (Collection <?> c ) {
151+ return keySet .containsAll (c );
152+ }
153+
154+ @ Override
155+ public Iterator <E > iterator () {
156+ return keySet .iterator ();
157+ }
158+
159+ @ Override
160+ public Object [] toArray () {
161+ return keySet .toArray ();
162+ }
163+
164+ @ Override
165+ public <T > T [] toArray (T [] a ) {
166+ return keySet .toArray (a );
167+ }
168+
169+ @ Override
170+ public boolean add (E e ) {
171+ return map .put (e , Boolean .TRUE ) == null ;
172+ }
173+
174+ @ Override
175+ public boolean remove (Object o ) {
176+ return map .remove (o ) != null ;
177+ }
178+
179+ @ Override
180+ public boolean removeAll (Collection <?> c ) {
181+ return keySet .removeAll (c );
182+ }
183+
184+ @ Override
185+ public boolean retainAll (Collection <?> c ) {
186+ return keySet .retainAll (c );
187+ }
188+
189+ @ Override
190+ public void clear () {
191+ map .clear ();
192+ }
193+
194+ @ Override
195+ public boolean equals (Object o ) {
196+ return o == this || keySet .equals (o );
197+ }
198+
199+ @ Override
200+ public int hashCode () {
201+ return keySet .hashCode ();
202+ }
203+
204+ @ Override
205+ public String toString () {
206+ return keySet .toString ();
207+ }
208+
209+ private void readObject (ObjectInputStream in ) throws IOException , ClassNotFoundException {
210+ in .defaultReadObject ();
211+ keySet = map .keySet ();
212+ }
90213 }
214+
91215}
0 commit comments