001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.collections.map;
018
019 import java.io.IOException;
020 import java.io.ObjectInputStream;
021 import java.io.ObjectOutputStream;
022 import java.io.Serializable;
023
024 /**
025 * A <code>Map</code> implementation that allows mappings to be
026 * removed by the garbage collector.
027 * <p>
028 * When you construct a <code>ReferenceMap</code>, you can specify what kind
029 * of references are used to store the map's keys and values.
030 * If non-hard references are used, then the garbage collector can remove
031 * mappings if a key or value becomes unreachable, or if the JVM's memory is
032 * running low. For information on how the different reference types behave,
033 * see {@link java.lang.ref.Reference Reference}.
034 * <p>
035 * Different types of references can be specified for keys and values.
036 * The keys can be configured to be weak but the values hard,
037 * in which case this class will behave like a
038 * <a href="http://java.sun.com/j2se/1.4/docs/api/java/util/WeakHashMap.html">
039 * <code>WeakHashMap</code></a>. However, you can also specify hard keys and
040 * weak values, or any other combination. The default constructor uses
041 * hard keys and soft values, providing a memory-sensitive cache.
042 * <p>
043 * This map is similar to
044 * {@link org.apache.commons.collections.map.ReferenceIdentityMap ReferenceIdentityMap}.
045 * It differs in that keys and values in this class are compared using <code>equals()</code>.
046 * <p>
047 * This {@link java.util.Map Map} implementation does <i>not</i> allow null elements.
048 * Attempting to add a null key or value to the map will raise a <code>NullPointerException</code>.
049 * <p>
050 * This implementation is not synchronized.
051 * You can use {@link java.util.Collections#synchronizedMap} to
052 * provide synchronized access to a <code>ReferenceMap</code>.
053 * Remember that synchronization will not stop the garbage collecter removing entries.
054 * <p>
055 * All the available iterators can be reset back to the start by casting to
056 * <code>ResettableIterator</code> and calling <code>reset()</code>.
057 * <p>
058 * <strong>Note that ReferenceMap is not synchronized and is not thread-safe.</strong>
059 * If you wish to use this map from multiple threads concurrently, you must use
060 * appropriate synchronization. The simplest approach is to wrap this map
061 * using {@link java.util.Collections#synchronizedMap}. This class may throw
062 * exceptions when accessed by concurrent threads without synchronization.
063 * <p>
064 * NOTE: As from Commons Collections 3.1 this map extends <code>AbstractReferenceMap</code>
065 * (previously it extended AbstractMap). As a result, the implementation is now
066 * extensible and provides a <code>MapIterator</code>.
067 *
068 * @see java.lang.ref.Reference
069 *
070 * @since Commons Collections 3.0 (previously in main package v2.1)
071 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
072 *
073 * @author Paul Jack
074 * @author Stephen Colebourne
075 */
076 public class ReferenceMap extends AbstractReferenceMap implements Serializable {
077
078 /** Serialization version */
079 private static final long serialVersionUID = 1555089888138299607L;
080
081 /**
082 * Constructs a new <code>ReferenceMap</code> that will
083 * use hard references to keys and soft references to values.
084 */
085 public ReferenceMap() {
086 super(HARD, SOFT, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, false);
087 }
088
089 /**
090 * Constructs a new <code>ReferenceMap</code> that will
091 * use the specified types of references.
092 *
093 * @param keyType the type of reference to use for keys;
094 * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
095 * @param valueType the type of reference to use for values;
096 * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
097 */
098 public ReferenceMap(int keyType, int valueType) {
099 super(keyType, valueType, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, false);
100 }
101
102 /**
103 * Constructs a new <code>ReferenceMap</code> that will
104 * use the specified types of references.
105 *
106 * @param keyType the type of reference to use for keys;
107 * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
108 * @param valueType the type of reference to use for values;
109 * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
110 * @param purgeValues should the value be automatically purged when the
111 * key is garbage collected
112 */
113 public ReferenceMap(int keyType, int valueType, boolean purgeValues) {
114 super(keyType, valueType, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, purgeValues);
115 }
116
117 /**
118 * Constructs a new <code>ReferenceMap</code> with the
119 * specified reference types, load factor and initial
120 * capacity.
121 *
122 * @param keyType the type of reference to use for keys;
123 * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
124 * @param valueType the type of reference to use for values;
125 * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
126 * @param capacity the initial capacity for the map
127 * @param loadFactor the load factor for the map
128 */
129 public ReferenceMap(int keyType, int valueType, int capacity, float loadFactor) {
130 super(keyType, valueType, capacity, loadFactor, false);
131 }
132
133 /**
134 * Constructs a new <code>ReferenceMap</code> with the
135 * specified reference types, load factor and initial
136 * capacity.
137 *
138 * @param keyType the type of reference to use for keys;
139 * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
140 * @param valueType the type of reference to use for values;
141 * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
142 * @param capacity the initial capacity for the map
143 * @param loadFactor the load factor for the map
144 * @param purgeValues should the value be automatically purged when the
145 * key is garbage collected
146 */
147 public ReferenceMap(int keyType, int valueType, int capacity,
148 float loadFactor, boolean purgeValues) {
149 super(keyType, valueType, capacity, loadFactor, purgeValues);
150 }
151
152 //-----------------------------------------------------------------------
153 /**
154 * Write the map out using a custom routine.
155 */
156 private void writeObject(ObjectOutputStream out) throws IOException {
157 out.defaultWriteObject();
158 doWriteObject(out);
159 }
160
161 /**
162 * Read the map in using a custom routine.
163 */
164 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
165 in.defaultReadObject();
166 doReadObject(in);
167 }
168
169 }