001 /*--------------------------------------------------------------------------+ 002 $Id: IdentityHashSet.java 26283 2010-02-18 11:18:57Z juergens $ 003 | | 004 | Copyright 2005-2010 Technische Universitaet Muenchen | 005 | | 006 | Licensed under the Apache License, Version 2.0 (the "License"); | 007 | you may not use this file except in compliance with the License. | 008 | You may obtain a copy of the License at | 009 | | 010 | http://www.apache.org/licenses/LICENSE-2.0 | 011 | | 012 | Unless required by applicable law or agreed to in writing, software | 013 | distributed under the License is distributed on an "AS IS" BASIS, | 014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 015 | See the License for the specific language governing permissions and | 016 | limitations under the License. | 017 +--------------------------------------------------------------------------*/ 018 package edu.tum.cs.commons.collections; 019 020 import java.util.AbstractSet; 021 import java.util.Collection; 022 import java.util.IdentityHashMap; 023 import java.util.Iterator; 024 025 /** 026 * This class implements a set based on referential equality similar to JDK 027 * class {@link IdentityHashMap}. This class can be e.g. used to implement 028 * listener lists that should not rely on the listeners <code>equals()</code>-methods. 029 * <p> 030 * The implementation is based on class {@link java.util.HashSet} that also uses 031 * an underlying hash map. 032 * 033 * 034 * @author Florian Deissenboeck 035 * @author $Author: juergens $ 036 * @version $Rev: 26283 $ 037 * @levd.rating GREEN Hash: A3753EB461A1466EFCA699DCE847468B 038 */ 039 public class IdentityHashSet<E> extends AbstractSet<E> { 040 041 /** Dummy object for the map. */ 042 private static final Object PRESENT = new Object(); 043 044 /** The map that actually stores the values. */ 045 private final IdentityHashMap<E, Object> map; 046 047 /** Create new identity hash set. */ 048 public IdentityHashSet() { 049 map = new IdentityHashMap<E, Object>(); 050 } 051 052 /** Create new identity hash set from an existing collection. */ 053 public IdentityHashSet(Collection<? extends E> collection) { 054 this(collection.size()); 055 056 for (E e : collection) { 057 add(e); 058 } 059 } 060 061 /** Create new identity hash set with an expected maximum size. */ 062 public IdentityHashSet(int expectedMaxSize) { 063 map = new IdentityHashMap<E, Object>(expectedMaxSize); 064 } 065 066 /** 067 * Adds the specified element to this set if it is not already present. 068 * 069 * @param o 070 * element to be added to this set. 071 * @return <tt>true</tt> if the set did not already contain the specified 072 * element. 073 */ 074 @Override 075 public boolean add(E o) { 076 return map.put(o, PRESENT) == null; 077 } 078 079 /** 080 * Removes all of the elements from this set. 081 */ 082 @Override 083 public void clear() { 084 map.clear(); 085 } 086 087 /** 088 * Returns a shallow copy of this <tt>IdentityHashSet</tt> instance: the 089 * elements themselves are not cloned. 090 * 091 * @return a shallow copy of this set. 092 */ 093 @Override 094 public IdentityHashSet<E> clone() { 095 return new IdentityHashSet<E>(this); 096 } 097 098 /** 099 * Returns <tt>true</tt> if this set contains the specified element. 100 * 101 * @param o 102 * element whose presence in this set is to be tested. 103 * @return <tt>true</tt> if this set contains the specified element. 104 */ 105 @Override 106 public boolean contains(Object o) { 107 return map.containsKey(o); 108 } 109 110 /** 111 * Returns <tt>true</tt> if this set contains no elements. 112 * 113 * @return <tt>true</tt> if this set contains no elements. 114 */ 115 @Override 116 public boolean isEmpty() { 117 return map.isEmpty(); 118 } 119 120 /** Return iterator over the set. */ 121 @Override 122 public Iterator<E> iterator() { 123 return map.keySet().iterator(); 124 } 125 126 /** 127 * Removes the specified element from this set if it is present. 128 * 129 * @param o 130 * object to be removed from this set, if present. 131 * @return <tt>true</tt> if the set contained the specified element. 132 */ 133 @Override 134 public boolean remove(Object o) { 135 return map.remove(o) == PRESENT; 136 } 137 138 /** 139 * Get set size. 140 */ 141 @Override 142 public int size() { 143 return map.size(); 144 } 145 146 }