com.unboundid.util.WeakHashSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unboundid-ldapsdk Show documentation
Show all versions of unboundid-ldapsdk Show documentation
The UnboundID LDAP SDK for Java is a fast, comprehensive, and easy-to-use
Java API for communicating with LDAP directory servers and performing
related tasks like reading and writing LDIF, encoding and decoding data
using base64 and ASN.1 BER, and performing secure communication. This
package contains the Standard Edition of the LDAP SDK, which is a
complete, general-purpose library for communicating with LDAPv3 directory
servers.
/*
* Copyright 2011-2018 Ping Identity Corporation
* All Rights Reserved.
*/
/*
* Copyright (C) 2011-2018 Ping Identity Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.util;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
/**
* This class provides a weak hash set, which maintains weak references to the
* elements it contains, so that they will be removed automatically once there
* are no more normal references to them.
*
* Note that because this set uses weak references, elements may disappear from
* the set at any time without being explicitly removed. This means that care
* must be taken to ensure that the result of one method must not be considered
* authoritative for subsequent calls to the same method or other methods in
* this class.
*
* @param The type of element held in this set.
*/
@Mutable()
@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
public final class WeakHashSet
implements Set
{
// The map that will be used to provide the set implementation.
private final WeakHashMap> m;
/**
* Creates a new weak hash set with the default initial capacity.
*/
public WeakHashSet()
{
m = new WeakHashMap<>(16);
}
/**
* Creates a new weak hash set with the specified initial capacity.
*
* @param initialCapacity The initial capacity for this weak hash set. It
* must not be {@code null}.
*/
public WeakHashSet(final int initialCapacity)
{
m = new WeakHashMap<>(initialCapacity);
}
/**
* Clears the contents of this set.
*/
@Override()
public void clear()
{
m.clear();
}
/**
* Indicates whether this set is currently empty.
*
* @return {@code true} if this set is empty, or {@code false} if not.
*/
@Override()
public boolean isEmpty()
{
return m.isEmpty();
}
/**
* Retrieves the number of elements currently held in this set.
*
* @return The number of elements currently held in this set.
*/
@Override()
public int size()
{
return m.size();
}
/**
* Indicates whether this set contains the specified element.
*
* @param e The element for which to make the determination.
*
* @return {@code true} if this set contains the specified element, or
* {@code false} if not.
*/
@Override()
public boolean contains(final Object e)
{
return m.containsKey(e);
}
/**
* Indicates whether this set currently contains all of the elements in the
* provided collection.
*
* @param c The collection for which to make the determination.
*
* @return {@code true} if this set currently contains all of the elements in
* the provided collection, or {@code false} if not.
*/
@Override()
public boolean containsAll(final Collection> c)
{
return m.keySet().containsAll(c);
}
/**
* Retrieves the existing instance of the provided element from this set.
*
* @param e The object for which to obtain the existing element.
*
* @return The existing instance of the provided element, or {@code null} if
* the provided element is not contained in this set.
*/
public T get(final T e)
{
final WeakReference r = m.get(e);
if (r == null)
{
return null;
}
else
{
return r.get();
}
}
/**
* Adds the provided element to this set, if it does not already exist.
*
* @param e The element to be added to the set if it does not already exist.
*
* @return {@code true} if the element was added to the set (because it was
* not already present), or {@code false} if the element was not
* added (because it was already in the set).
*/
@Override()
public boolean add(final T e)
{
if (m.containsKey(e))
{
return false;
}
else
{
m.put(e, new WeakReference<>(e));
return true;
}
}
/**
* Adds any elements from the provided collection to this set if they were
* not already present.
*
* @param c The collection containing elements to add.
*
* @return {@code true} if at least one of the elements was not already in
* the set and was added, or {@code false} if no elements were added
* because they were already all present.
*/
@Override()
public boolean addAll(final Collection extends T> c)
{
boolean changed = false;
for (final T e : c)
{
if (! m.containsKey(e))
{
m.put(e, new WeakReference<>(e));
changed = true;
}
}
return changed;
}
/**
* Adds the provided element to the set if it does not already exist, and
* retrieves the value stored in the set.
*
* @param e The element to be added to the set if it does not already exist.
*
* @return An existing version of the provided element if it was already in
* the set, or the provided object if it was just added.
*/
public T addAndGet(final T e)
{
final WeakReference r = m.get(e);
if (r != null)
{
final T existingElement = r.get();
if (existingElement != null)
{
return existingElement;
}
}
m.put(e, new WeakReference<>(e));
return e;
}
/**
* Removes the specified element from this set, if it exists.
*
* @param e The element to be removed from this set.
*
* @return {@code true} if the element existed in the set and was removed, or
* {@code false} if not.
*/
@Override()
public boolean remove(final Object e)
{
return (m.remove(e) != null);
}
/**
* Removes all of the elements of the provided collection from this set.
*
* @param c The collection containing the elements to remove from this set.
*
* @return {@code true} if at least one of the elements from the provided
* collection were contained in and therefore removed from the set,
* or {@code false} if none of the elements in the given collection
* were contained in this set.
*/
@Override()
public boolean removeAll(final Collection> c)
{
boolean changed = false;
for (final Object o : c)
{
final Object e = m.remove(o);
if (e != null)
{
changed = true;
}
}
return changed;
}
/**
* Removes all elements from this set which are not contained in the provided
* collection.
*
* @param c The collection of elements to be retained.
*
* @return {@code true} if this set contained at least one element not in the
* provided collection that was therefore removed, or {@code false}
* if this set did not have any elements that were not in the
* provided collection.
*/
@Override()
public boolean retainAll(final Collection> c)
{
boolean changed = false;
final Iterator>> iterator =
m.entrySet().iterator();
while (iterator.hasNext())
{
final Map.Entry> e = iterator.next();
if (! c.contains(e.getKey()))
{
iterator.remove();
changed = true;
}
}
return changed;
}
/**
* Retrieves an iterator across all elements in this set.
*
* @return An iterator across all elements in this set.
*/
@Override()
public Iterator iterator()
{
return m.keySet().iterator();
}
/**
* Retrieves an array containing all of the elements currently held in this
* set.
*
* @return An array containing all of the elements currently held in this
* set.
*/
@Override()
public Object[] toArray()
{
return m.keySet().toArray();
}
/**
* Retrieves an array containing all of the elements currently held in this
* set.
*
* @param a An array into which the elements will be added if there is
* sufficient space.
*
* @param The type of element for the given array.
*
* @return The provided array (with the first {@code null} element depicting
* the end of the set elements if the given array is larger than this
* set), or a newly-allocated array if the provided array was not
* large enough.
*/
@Override()
public E[] toArray(final E[] a)
{
return m.keySet().toArray(a);
}
/**
* Retrieves a hash code for this set.
*
* @return A hash code for this set.
*/
@Override()
public int hashCode()
{
return m.keySet().hashCode();
}
/**
* Indicates whether the provided object is equal to this set.
*
* @param o The object for which to make the determination.
*
* @return {@code true} if the provided object is a non-{@code null} set with
* the same elements as this set, or {@code false} if not.
*/
@Override()
public boolean equals(final Object o)
{
return ((o != null) && (o instanceof Set) && m.keySet().equals(o));
}
/**
* Retrieves a string representation of this set.
*
* @return A string representation of this set.
*/
@Override()
public String toString()
{
return m.keySet().toString();
}
}