Java/Collections Data Structure/Weak Set — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 10:26, 1 июня 2010
Содержание
A weak HashSet: element stored in the WeakHashSet might be garbage collected
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.HashSet; import java.util.Iterator; /**
* A weak HashSet. An element stored in the WeakHashSet might be * garbage collected, if there is no strong reference to this element. */
public class WeakHashSet extends HashSet {
/** * Helps to detect garbage collected values. */ ReferenceQueue queue = new ReferenceQueue(); /** * Returns an iterator over the elements in this set. The elements * are returned in no particular order. * * @return an Iterator over the elements in this set. */ public Iterator iterator() { // remove garbage collected elements processQueue(); // get an iterator of the superclass WeakHashSet final Iterator i = super.iterator(); return new Iterator() { public boolean hasNext() { return i.hasNext(); } public Object next() { // unwrap the element return getReferenceObject((WeakReference) i.next()); } public void remove() { // remove the element from the HashSet i.remove(); } }; } /** * Returnstrue
if this set contains the specified element. * * @param o element whose presence in this set is to be tested. * @returntrue
if this set contains the specified element. */ public boolean contains(Object o) { return super.contains(WeakElement.create(o)); } /** * Adds the specified element to this set if it is not already * present. * * @param o element to be added to this set. * @returntrue
if the set did not already contain the specified * element. */ public boolean add(Object o) { processQueue(); return super.add(WeakElement.create(o, this.queue)); } /** * Removes the given element from this set if it is present. * * @param o object to be removed from this set, if present. * @returntrue
if the set contained the specified element. */ public boolean remove(Object o) { boolean ret = super.remove(WeakElement.create(o)); processQueue(); return ret; } /** * A convenience method to return the object held by the * weak reference ornull
if it does not exist. */ private final Object getReferenceObject(WeakReference ref) { return (ref == null) ? null : ref.get(); } /** * Removes all garbage collected values with their keys from the map. * Since we don"t know how much the ReferenceQueue.poll() operation * costs, we should call it only in the add() method. */ private final void processQueue() { WeakElement wv = null; while ((wv = (WeakElement) this.queue.poll()) != null) { super.remove(wv); } } /** * A WeakHashSet stores objects of class WeakElement. * A WeakElement wraps the element that should be stored in the WeakHashSet. * WeakElement inherits from java.lang.ref.WeakReference. * It redefines equals and hashCode which delegate to the corresponding methods * of the wrapped element. */ static private class WeakElement extends WeakReference { private int hash; /* Hashcode of key, stored here since the key may be tossed by the GC */ private WeakElement(Object o) { super(o); hash = o.hashCode(); } private WeakElement(Object o, ReferenceQueue q) { super(o, q); hash = o.hashCode(); } private static WeakElement create(Object o) { return (o == null) ? null : new WeakElement(o); } private static WeakElement create(Object o, ReferenceQueue q) { return (o == null) ? null : new WeakElement(o, q); } /* A WeakElement is equal to another WeakElement iff they both refer to objects that are, in turn, equal according to their own equals methods */ public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof WeakElement)) return false; Object t = this.get(); Object u = ((WeakElement) o).get(); if (t == u) return true; if ((t == null) || (u == null)) return false; return t.equals(u); } public int hashCode() { return hash; } }
}
</source>
Set which holds its members by using of WeakReferences.
<source lang="java">
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun * Microsystems, Inc. All Rights Reserved. * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. */
import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; /** Set which holds its members by using of WeakReferences.
- MT level: unsafe.
Note: as of JDK 6.0 (b51), you can instead use *
* Set<T> s = Collections.newSetFromMap(new WeakHashMap<T, Boolean>()); *
- @author Ales Novak
- /
public class WeakSet<E> extends AbstractSet<E> implements Cloneable, Serializable {
static final long serialVersionUID = 3062376055928236721L; /** load factor */ private float loadFactor; /** Number of items. */ private int size; /** Modification count */ private long modcount; /** Reference queue of collected weak refs */ private transient ReferenceQueue<E> refq; /** Count of null in this set */ long nullCount; /** An array of Entries */ private transient Entry<E>[] entries; transient Entry<E> iterChain; /** Constructs a new set. */ public WeakSet() { this(11, 0.75f); } /** Constructs a new set containing the elements in the specified collection. * @param c a collection to add */ public WeakSet(Collection<? extends E> c) { this(); addAll(c); } /** Constructs a new, empty set; * @param initialCapacity initial capacity */ public WeakSet(int initialCapacity) { this(initialCapacity, 0.75f); } /** Constructs a new, empty set; * * @param initialCapacity initial capacity * @param loadFactor load factor */ public WeakSet(int initialCapacity, float loadFactor) { if ((initialCapacity <= 0) || (loadFactor <= 0)) { throw new IllegalArgumentException(); } size = 0; modcount = 0; this.loadFactor = loadFactor; nullCount = 0; refq = new ReferenceQueue<E>(); entries = Entry.createArray(initialCapacity); iterChain = null; } /** * logs iterator chain (for debugging) * @param msg */ void logIterChain(String msg) { Logger log = Logger.getLogger(WeakSet.class.getName()); log.log(Level.FINE, msg); if (iterChain == null) { log.log(Level.FINE, "Empty"); return; } StringBuilder str = new StringBuilder(); Entry<E> it = iterChain; str.append(size + ": "); while (it != null) { str.append(it.get() + "(" + it.hashcode + ")" + "->"); it = it.iterChainNext; } log.log(Level.FINE, str.toString()); } /** Adds the specified element to this set if it is not already present. * * @param o an Object to add */ public boolean add(E o) { if (o == null) { size++; nullCount++; modcount++; return true; } Entry e = object2Entry(o); if (e != null) { return false; } modcount++; size++; int hash = hashIt(o); Entry<E> next = entries[hash]; iterChain = entries[hash] = new Entry<E>(this, o, refq, next, iterChain); rehash(); return true; } /** Removes all of the elements from this set. */ public void clear() { for (int i = 0; i < entries.length; i++) { entries[i] = null; } nullCount = 0; modcount++; size = 0; iterChain = null; } /** Returns a shallow copy of this WeakSet instance: the elements themselves are not cloned. */ public Object clone() { WeakSet<E> nws = new WeakSet<E>(1, loadFactor); nws.size = size; nws.nullCount = nullCount; Entry<E>[] cloned = Entry.createArray(entries.length); nws.entries = cloned; for (int i = 0; i < cloned.length; i++) { Object ref; if ((entries[i] == null) || ((ref = entries[i].get()) == null)) { cloned[i] = null; } else { cloned[i] = ((entries[i] == null) ? null : entries[i].clone(nws.refq)); ref = null; } // chains into nws iterator chain Entry<E> entry = cloned[i]; while (entry != null) { entry.chainIntoIter(nws.iterChain); nws.iterChain = entry; entry = entry.next; } } return nws; } /** Returns true if this set contains the specified element. * * @param o an Object to examine */ public boolean contains(Object o) { if (o == null) { return nullCount > 0; } return object2Entry(o) != null; } /** Returns true if this set contains no elements. */ public boolean isEmpty() { return ((nullCount == 0) && (size() == 0)); } /** Returns an iterator over the elements in this set. */ public Iterator<E> iterator() { return new WeakSetIterator(); } /** Removes the given element from this set if it is present. * * @param o an Object to remove * @return true if and only if the Object was successfuly removed. */ public boolean remove(Object o) { if (o == null) { if (nullCount > 0) { nullCount--; modcount++; size--; } return true; } Entry e = object2Entry(o); if (e != null) { modcount++; size--; e.remove(); rehash(); return true; } return false; } /** @return the number of elements in this set (its cardinality). */ public int size() { checkRefQueue(); return size; } public <T> T[] toArray(T[] array) { ArrayList<E> list = new ArrayList<E>(array.length); Iterator<E> it = iterator(); while (it.hasNext()) { list.add(it.next()); } return list.toArray(array); } public Object[] toArray() { ArrayList<E> list = new ArrayList<E>(); Iterator<E> it = iterator(); while (it.hasNext()) { list.add(it.next()); } return list.toArray(); } // #14772 public String toString() { StringBuffer buf = new StringBuffer(); Iterator e = iterator(); buf.append("["); while (e.hasNext()) { buf.append(String.valueOf(e.next())); if (e.hasNext()) { buf.append(", "); } } buf.append("]"); return buf.toString(); } /** Checks if the queue is empty if not pending weak refs are removed. */ void checkRefQueue() { for (;;) { Entry entry = Entry.class.cast(refq.poll()); if (entry == null) { break; } entry.remove(); size--; } } /** @return modcount */ long modCount() { return modcount; } /** @return an index to entries array */ int hashIt(Object o) { return (o.hashCode() & 0x7fffffff) % entries.length; } /** rehashes this Set */ void rehash() { /* float currentLF = ((float) size) / ((float) entries.length); if (currentLF < loadFactor) { return; } */ } /** @return an Entry with given object */ private Entry object2Entry(Object o) { checkRefQueue(); // clear ref q int hash = hashIt(o); Entry e = entries[hash]; if (e == null) { return null; } while ((e != null) && !e.equals(o)) { e = e.next; } return e; } private void writeObject(ObjectOutputStream obtos) throws IOException { obtos.defaultWriteObject(); obtos.writeObject(toArray()); } @SuppressWarnings("unchecked") private void readObject(ObjectInputStream obtis) throws IOException, ClassNotFoundException { obtis.defaultReadObject(); Object[] arr = (Object[]) obtis.readObject(); entries = new Entry[(int) (size * 1.5)]; refq = new ReferenceQueue<E>(); for (int i = 0; i < arr.length; i++) { add((E)arr[i]); } } class WeakSetIterator implements Iterator<E> { Entry<E> current; Entry<E> next; E currentObj; E nextObj; final long myModcount; long myNullCount; WeakSetIterator() { myModcount = modCount(); myNullCount = nullCount; current = null; next = null; Entry<E> ee = iterChain; if (ee == null) { return; } E o = ee.get(); while (ee.isEnqueued()) { ee = ee.iterChainNext; if (ee == null) { return; } o = ee.get(); } nextObj = o; next = ee; } public boolean hasNext() { checkModcount(); return ((myNullCount > 0) || (next != null)); } public E next() { checkModcount(); checkRefQueue(); if (myNullCount > 0) { myNullCount--; return null; } else { if (next == null) { throw new java.util.NoSuchElementException(); } current = next; currentObj = nextObj; // move to next requested do { next = next.iterChainNext; if (next == null) { break; } nextObj = next.get(); } while (next.isEnqueued()); return currentObj; } } public void remove() { checkModcount(); if (current == null) { throw new IllegalStateException(); } current.remove(); size--; } void checkModcount() { if (myModcount != modCount()) { throw new ConcurrentModificationException(); } } } /** Entries of this set */ static class Entry<E> extends WeakReference<E> { /** reference to outer WeakSet */ private WeakSet<E> set; // double linked list Entry<E> prev; Entry<E> next; private final int hashcode; Entry<E> iterChainNext; Entry<E> iterChainPrev; Entry(WeakSet<E> set, E referenced, ReferenceQueue<E> q, Entry<E> next, Entry<E> nextInIter) { super(referenced, q); this.set = set; this.next = next; this.prev = null; if (next != null) { next.prev = this; } if (referenced != null) { hashcode = set.hashIt(referenced); } else { hashcode = 0; } chainIntoIter(nextInIter); } @SuppressWarnings("unchecked") static final <E> Entry<E>[] createArray(int size) { return new Entry[size]; } void chainIntoIter(Entry<E> nextInIter) { iterChainNext = nextInIter; if (nextInIter != null) { nextInIter.iterChainPrev = this; } } /** deques itself */ void remove() { if (prev != null) { prev.next = next; } if (next != null) { next.prev = prev; } if (iterChainNext != null) { iterChainNext.iterChainPrev = iterChainPrev; } if (iterChainPrev != null) { iterChainPrev.iterChainNext = iterChainNext; } else { // root set.iterChain = iterChainNext; } if (set.entries[hashcode] == this) { set.entries[hashcode] = next; } prev = null; next = null; iterChainNext = null; iterChainPrev = null; } public int hashCode() { return hashcode; } public boolean equals(Object o) { Object oo = get(); if (oo == null) { return false; } else { return oo.equals(o); } } public Entry<E> clone(ReferenceQueue<E> q) { return new Entry<E>(set, get(), q, next != null ? next.clone(q) : null, null); } }
}
</source>
Weak HashSet
<source lang="java">
/*
* The contents of this file are subject to the terms * of the Common Development and Distribution License * (the "License"). You may not use this file except * in compliance with the License. * * You can obtain a copy of the license at * glassfish/bootstrap/legal/CDDLv1.0.txt or * https://glassfish.dev.java.net/public/CDDLv1.0.html. * See the License for the specific language governing * permissions and limitations under the License. * * When distributing Covered Code, include this CDDL * HEADER in each file and include the License file at * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable, * add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your * own identifying information: Portions Copyright [yyyy] * [name of copyright owner] */
/*
* Copyright 2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.HashSet; import java.util.Iterator; /**
* A weak HashSet. An element stored in the WeakHashSet might be * garbage collected, if there is no strong reference to this element. */
public class WeakHashSet extends HashSet {
/** * Helps to detect garbage collected values. */ ReferenceQueue queue = new ReferenceQueue(); /** * Returns an iterator over the elements in this set. The elements * are returned in no particular order. * * @return an Iterator over the elements in this set. */ public Iterator iterator() { // remove garbage collected elements processQueue(); // get an iterator of the superclass WeakHashSet final Iterator i = super.iterator(); return new Iterator() { public boolean hasNext() { return i.hasNext(); } public Object next() { // unwrap the element return getReferenceObject((WeakReference) i.next()); } public void remove() { // remove the element from the HashSet i.remove(); } }; } /** * Returnstrue
if this set contains the specified element. * * @param o element whose presence in this set is to be tested. * @returntrue
if this set contains the specified element. */ public boolean contains(Object o) { return super.contains(WeakElement.create(o)); } /** * Adds the specified element to this set if it is not already * present. * * @param o element to be added to this set. * @returntrue
if the set did not already contain the specified * element. */ public boolean add(Object o) { processQueue(); return super.add(WeakElement.create(o, this.queue)); } /** * Removes the given element from this set if it is present. * * @param o object to be removed from this set, if present. * @returntrue
if the set contained the specified element. */ public boolean remove(Object o) { boolean ret = super.remove(WeakElement.create(o)); processQueue(); return ret; } /** * A convenience method to return the object held by the * weak reference ornull
if it does not exist. */ private final Object getReferenceObject(WeakReference ref) { return (ref == null) ? null : ref.get(); } /** * Removes all garbage collected values with their keys from the map. * Since we don"t know how much the ReferenceQueue.poll() operation * costs, we should call it only in the add() method. */ private final void processQueue() { WeakElement wv = null; while ((wv = (WeakElement) this.queue.poll()) != null) { super.remove(wv); } } /** * A WeakHashSet stores objects of class WeakElement. * A WeakElement wraps the element that should be stored in the WeakHashSet. * WeakElement inherits from java.lang.ref.WeakReference. * It redefines equals and hashCode which delegate to the corresponding methods * of the wrapped element. */ static private class WeakElement extends WeakReference { private int hash; /* Hashcode of key, stored here since the key may be tossed by the GC */ private WeakElement(Object o) { super(o); hash = o.hashCode(); } private WeakElement(Object o, ReferenceQueue q) { super(o, q); hash = o.hashCode(); } private static WeakElement create(Object o) { return (o == null) ? null : new WeakElement(o); } private static WeakElement create(Object o, ReferenceQueue q) { return (o == null) ? null : new WeakElement(o, q); } /* A WeakElement is equal to another WeakElement iff they both refer to objects that are, in turn, equal according to their own equals methods */ public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof WeakElement)) return false; Object t = this.get(); Object u = ((WeakElement) o).get(); if (t == u) return true; if ((t == null) || (u == null)) return false; return t.equals(u); } public int hashCode() { return hash; } }
}
</source>
Weak HashSet from objectweb jac
<source lang="java">
// Revised from objectweb jac import java.lang.Cloneable; import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; import java.util.Set; import java.util.WeakHashMap;
public class WeakHashSet extends AbstractSet
implements Set
{
private transient WeakHashMap map; public WeakHashSet() { map = new WeakHashMap(); } public WeakHashSet(Collection c) { map = new WeakHashMap(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } public WeakHashSet(int initialCapacity, float loadFactor) { map = new WeakHashMap(initialCapacity, loadFactor); } public WeakHashSet(int initialCapacity) { map = new WeakHashMap(initialCapacity); } public Iterator iterator() { return map.keySet().iterator(); } public int size() { return map.size(); } public boolean isEmpty() { return map.isEmpty(); } public boolean contains(Object o) { return map.containsKey(o); } public boolean add(Object o) { return map.put(o, Boolean.TRUE)==null; } public boolean remove(Object o) { return map.remove(o)==Boolean.TRUE; } public void clear() { map.clear(); }
}
</source>
Weak HashSet from TJDO
<source lang="java">
/*
* Copyright 2004 (C) TJDO. * All rights reserved. * * This software is distributed under the terms of the TJDO License version 1.0. * See the terms of the TJDO License in the documentation provided with this software. * * $Id: WeakHashSet.java,v 1.1 2004/08/09 23:53:35 jackknifebarber Exp $ */
import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; import java.util.Set; import java.util.WeakHashMap;
/**
* A Set implementation with weak elements. * This class implements the Set interface, backed by a hash table with * weak keys (actually a WeakHashMap instance). * An element in a WeakHashSet will automatically be removed when it * is no longer in ordinary use. * More precisely, the presence of an element will not prevent it from being * discarded by the garbage collector, that is, made finalizable, finalized, * and then reclaimed. * When a element has been discarded it is effectively removed from the set, * so this class behaves somewhat differently than other Set * implementations. * <p> * The null element is supported. * This class has performance characteristics similar to those of the * HashSet class, and has the same efficiency parameters of * initial capacity and load factor. * <p> * Like most collection classes, this class is not synchronized. * A synchronized WeakHashSet may be constructed using the * Collections.synchronizedSet method. * <p> * This class is intended primarily for use with objects whose * equals methods test for object identity using the * == operator. * Once such an object is discarded it can never be recreated, so it is * impossible to do a lookup of that key in a WeakHashSet at some later * time and be surprised that its entry has been removed. * This class will work perfectly well with objects whose equals * methods are not based upon object identity, such as String * instances. * With such recreatable objects however, the automatic removal of * WeakHashSet elements that have been discarded may prove to be * confusing. * <p> * The behavior of the WeakHashSet class depends in part upon the * actions of the garbage collector, so several familiar (though not required) * Set invariants do not hold for this class. * Because the garbage collector may discard elements at any time, a * WeakHashSet may behave as though an unknown thread is silently * removing elements. * In particular, even if you synchronize on a WeakHashSet instance and * invoke none of its mutator methods, it is possible for the size * method to return smaller values over time, for the isEmpty method to * return false and then true, for the contains * method to return true and later false for a given object, * for the add method to return true and the remove * method to return false for an element that previously appeared to be * in the set, and for successive examinations of the set to yield successively * smaller numbers of elements. * <p> * Each element in a WeakHashSet is stored indirectly as the referent * of a weak reference. * Therefore an element will automatically be removed only after the weak * references to it, both inside and outside of the set, have been cleared by * the garbage collector. * <p> * The iterators returned by this class are fail-fast: if the set is * structurally modified at any time after the iterator is created, in any way * except through the iterator"s own remove or add methods, * the iterator will throw a ConcurrentModificationException. * Thus, in the face of concurrent modification, the iterator fails quickly and * cleanly, rather than risking arbitrary, non-deterministic behavior at an * undetermined time in the future. * <p> * Note that the fail-fast behavior of an iterator cannot be guaranteed * as it is, generally speaking, impossible to make any hard guarantees in the * presence of unsynchronized concurrent modification. * Fail-fast iterators throw ConcurrentModificationException on a * best-effort basis. * Therefore, it would be wrong to write a program that depended on this * exception for its correctness: the fail-fast behavior of iterators * should be used only to detect bugs. * * * @author (borrowing * liberally from java.util.HashSet) * @version $Revision: 1.1 $ */
public class WeakHashSet extends AbstractSet implements Set {
/* Dummy value to associate with an Object in the backing Map. */ private static final Object PRESENT = new Object(); private final WeakHashMap map;
/** * Constructs a new, empty set; the backing WeakHashMap instance has * default initial capacity (16) and load factor (0.75). */ public WeakHashSet() { map = new WeakHashMap(); }
/** * Constructs a new set containing the elements in the specified * collection. The WeakHashMap is created with default load factor * (0.75) and an initial capacity sufficient to contain the elements in * the specified collection. * * @param c the collection whose elements are to be placed into this set. * @throws NullPointerException if the specified collection is null. */ public WeakHashSet(Collection c) { map = new WeakHashMap(Math.max((int)(c.size() / .75f) + 1, 16)); addAll(c); }
/** * Constructs a new, empty set; the backing WeakHashMap instance has * the specified initial capacity and the specified load factor. * * @param initialCapacity the initial capacity of the hash map. * @param loadFactor the load factor of the hash map. * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive. */ public WeakHashSet(int initialCapacity, float loadFactor) { map = new WeakHashMap(initialCapacity, loadFactor); }
/** * Constructs a new, empty set; the backing WeakHashMap instance has * the specified initial capacity and default load factor, which is * 0.75. * * @param initialCapacity the initial capacity of the hash table. * @throws IllegalArgumentException if the initial capacity is less * than zero. */ public WeakHashSet(int initialCapacity) { map = new WeakHashMap(initialCapacity); }
/** * Returns an iterator over the elements in this set. The elements * are returned in no particular order. * * @return an Iterator over the elements in this set. * @see "java.util.ConcurrentModificationException" */ public Iterator iterator() { return map.keySet().iterator(); }
/** * Returns the number of elements in this set (its cardinality). * * @return the number of elements. */ public int size() { return map.size(); }
/**
* Indicates whether the set is empty.
*
* @return true
if the set contains no elements.
*/
public boolean isEmpty()
{
return map.isEmpty();
}
/**
* Indicates whether the set contains the specified element.
*
* @param o the element to specify.
* @return true
if the set contains the specified element.
*/
public boolean contains(Object o)
{
return map.containsKey(o);
}
/**
* Adds the specified element to the set if it is not already
* present.
*
* @param o the element to be added.
* @return true
if the set did not already contain the specified
* element.
*/
public boolean add(Object o)
{
return map.put(o, PRESENT) == null;
}
/**
* Removes the specified element from the set if it is present.
*
* @param o the element to be removed.
* @return true
if the set contained the specified element.
*/
public boolean remove(Object o)
{
return map.remove(o) == PRESENT;
}
/** * Removes all of the elements from the set. */ public void clear() { map.clear(); }
}
</source>