001: /* IdentityHashSet.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Fri Sep 13 11:18:11 2002, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2002 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.util;
020:
021: import java.util.Collection;
022: import java.util.Set;
023: import java.util.AbstractSet;
024: import java.util.IdentityHashMap;
025: import java.util.Iterator;
026:
027: import org.zkoss.lang.Objects;
028:
029: /**
030: * Like java.util.InternalHashMap, it uses == and System.identityHashCode
031: * for doing HashSet.
032: *
033: * @author tomyeh
034: * @see IdentityComparator
035: */
036: public class IdentityHashSet extends AbstractSet implements Set,
037: Cloneable, java.io.Serializable {
038: private static final long serialVersionUID = 20060622L;
039:
040: private transient IdentityHashMap map;
041:
042: /**
043: * Constructs a new, empty set; the backing <tt>IdentityHashMap</tt>
044: * instance has default capacity (32).
045: */
046: public IdentityHashSet() {
047: map = new IdentityHashMap();
048: }
049:
050: /**
051: * Constructs a new set containing the elements in the specified
052: * collection.
053: *
054: * @param c the collection whose elements are to be placed into this set.
055: * @throws NullPointerException if the specified collection is null.
056: */
057: public IdentityHashSet(Collection c) {
058: map = new IdentityHashMap(Math.max((c.size() * 4) / 3, 16));
059: addAll(c);
060: }
061:
062: /**
063: * Constructs a new, empty set with the specified expected maximum size.
064: *
065: * @param expectedMaxSize the expected maximum size of the map.
066: * @throws IllegalArgumentException if <tt>expectedMaxSize</tt> is negative
067: */
068: public IdentityHashSet(int expectedMaxSize) {
069: map = new IdentityHashMap(expectedMaxSize);
070: }
071:
072: //-- Set --//
073: public Iterator iterator() {
074: return map.keySet().iterator();
075: }
076:
077: public int size() {
078: return map.size();
079: }
080:
081: public boolean isEmpty() {
082: return map.isEmpty();
083: }
084:
085: public boolean contains(Object o) {
086: return map.containsKey(o);
087: }
088:
089: public boolean add(Object o) {
090: return map.put(o, Objects.UNKNOWN) == null;
091: }
092:
093: public boolean remove(Object o) {
094: return map.remove(o) == Objects.UNKNOWN;
095: }
096:
097: public void clear() {
098: map.clear();
099: }
100:
101: public Object clone() {
102: try {
103: IdentityHashSet newSet = (IdentityHashSet) super .clone();
104: newSet.map = (IdentityHashMap) map.clone();
105: return newSet;
106: } catch (CloneNotSupportedException e) {
107: throw new InternalError();
108: }
109: }
110:
111: //-- Serializable --//
112: private synchronized void writeObject(java.io.ObjectOutputStream s)
113: throws java.io.IOException {
114: // Write out any hidden serialization magic
115: s.defaultWriteObject();
116:
117: // Write out size
118: s.writeInt(map.size());
119:
120: // Write out all elements in the proper order.
121: for (Iterator i = map.keySet().iterator(); i.hasNext();)
122: s.writeObject(i.next());
123: }
124:
125: private synchronized void readObject(java.io.ObjectInputStream s)
126: throws java.io.IOException, ClassNotFoundException {
127: // Read in any hidden serialization magic
128: s.defaultReadObject();
129:
130: // Read in size (number of Mappings)
131: int size = s.readInt();
132:
133: // Read in IdentityHashMap capacity and load factor and create backing IdentityHashMap
134: map = new IdentityHashMap((size * 4) / 3);
135: // Allow for 33% growth (i.e., capacity is >= 2* size()).
136:
137: // Read in all elements in the proper order.
138: for (int i = 0; i < size; i++) {
139: Object e = s.readObject();
140: map.put(e, Objects.UNKNOWN);
141: }
142: }
143: }
|