1. /*
  2. * Copyright 2003-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections.map;
  17. import java.io.IOException;
  18. import java.io.ObjectInputStream;
  19. import java.io.ObjectOutputStream;
  20. import java.io.Serializable;
  21. import java.util.Map;
  22. /**
  23. * A <code>Map</code> implementation that matches keys and values based
  24. * on <code>==</code> not <code>equals()</code>.
  25. * <p>
  26. * This map will violate the detail of various Map and map view contracts.
  27. * As a general rule, don't compare this map to other maps.
  28. *
  29. * @since Commons Collections 3.0
  30. * @version $Revision: 1.5 $ $Date: 2004/02/18 01:13:19 $
  31. *
  32. * @author java util HashMap
  33. * @author Stephen Colebourne
  34. */
  35. public class IdentityMap
  36. extends AbstractHashedMap implements Serializable, Cloneable {
  37. /** Serialisation version */
  38. private static final long serialVersionUID = 2028493495224302329L;
  39. /**
  40. * Constructs a new empty map with default size and load factor.
  41. */
  42. public IdentityMap() {
  43. super(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_THRESHOLD);
  44. }
  45. /**
  46. * Constructs a new, empty map with the specified initial capacity.
  47. *
  48. * @param initialCapacity the initial capacity
  49. * @throws IllegalArgumentException if the initial capacity is less than one
  50. */
  51. public IdentityMap(int initialCapacity) {
  52. super(initialCapacity);
  53. }
  54. /**
  55. * Constructs a new, empty map with the specified initial capacity and
  56. * load factor.
  57. *
  58. * @param initialCapacity the initial capacity
  59. * @param loadFactor the load factor
  60. * @throws IllegalArgumentException if the initial capacity is less than one
  61. * @throws IllegalArgumentException if the load factor is less than zero
  62. */
  63. public IdentityMap(int initialCapacity, float loadFactor) {
  64. super(initialCapacity, loadFactor);
  65. }
  66. /**
  67. * Constructor copying elements from another map.
  68. *
  69. * @param map the map to copy
  70. * @throws NullPointerException if the map is null
  71. */
  72. public IdentityMap(Map map) {
  73. super(map);
  74. }
  75. //-----------------------------------------------------------------------
  76. /**
  77. * Gets the hash code for the key specified.
  78. * This implementation uses the identity hash code.
  79. *
  80. * @param key the key to get a hash code for
  81. * @return the hash code
  82. */
  83. protected int hash(Object key) {
  84. return System.identityHashCode(key);
  85. }
  86. /**
  87. * Compares two keys for equals.
  88. * This implementation uses <code>==</code>.
  89. *
  90. * @param key1 the first key to compare
  91. * @param key2 the second key to compare
  92. * @return true if equal by identity
  93. */
  94. protected boolean isEqualKey(Object key1, Object key2) {
  95. return (key1 == key2);
  96. }
  97. /**
  98. * Compares two values for equals.
  99. * This implementation uses <code>==</code>.
  100. *
  101. * @param value1 the first value to compare
  102. * @param value2 the second value to compare
  103. * @return true if equal by identity
  104. */
  105. protected boolean isEqualValue(Object value1, Object value2) {
  106. return (value1 == value2);
  107. }
  108. /**
  109. * Creates an entry to store the data.
  110. * This implementation creates an IdentityEntry instance.
  111. *
  112. * @param next the next entry in sequence
  113. * @param hashCode the hash code to use
  114. * @param key the key to store
  115. * @param value the value to store
  116. * @return the newly created entry
  117. */
  118. protected HashEntry createEntry(HashEntry next, int hashCode, Object key, Object value) {
  119. return new IdentityEntry(next, hashCode, key, value);
  120. }
  121. //-----------------------------------------------------------------------
  122. /**
  123. * HashEntry
  124. */
  125. protected static class IdentityEntry extends HashEntry {
  126. protected IdentityEntry(HashEntry next, int hashCode, Object key, Object value) {
  127. super(next, hashCode, key, value);
  128. }
  129. public boolean equals(Object obj) {
  130. if (obj == this) {
  131. return true;
  132. }
  133. if (obj instanceof Map.Entry == false) {
  134. return false;
  135. }
  136. Map.Entry other = (Map.Entry) obj;
  137. return
  138. (getKey() == other.getKey()) &&
  139. (getValue() == other.getValue());
  140. }
  141. public int hashCode() {
  142. return System.identityHashCode(getKey()) ^
  143. System.identityHashCode(getValue());
  144. }
  145. }
  146. //-----------------------------------------------------------------------
  147. /**
  148. * Clones the map without cloning the keys or values.
  149. *
  150. * @return a shallow clone
  151. */
  152. public Object clone() {
  153. return super.clone();
  154. }
  155. /**
  156. * Write the map out using a custom routine.
  157. */
  158. private void writeObject(ObjectOutputStream out) throws IOException {
  159. out.defaultWriteObject();
  160. doWriteObject(out);
  161. }
  162. /**
  163. * Read the map in using a custom routine.
  164. */
  165. private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
  166. in.defaultReadObject();
  167. doReadObject(in);
  168. }
  169. }