📄 softrefhashmap.java
字号:
/* * Copyright 1999-2004 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. */package org.apache.commons.collections;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
/** <p>
* HashMap with SoftReference links to values which allows the values of the Map
* to be garbage collected by the JVM if it becomes low on memory.
* Derive from this class and
* override the factory method <code>createReference()</code> method to make
* a Map wrapped in other types of Reference.
* </p>
*
* <p>
* A synchronized version can be obtained with:
* <code>Collections.synchronizedMap( theMapToSynchronize )</code>
* </p>
*
* <p>
* <b>WARNING</b> the values() and entrySet() methods require optimisation
* like the standard {@link HashMap} implementations so that iteration
* over this Map is efficient.
* </p>
*
* @since 1.0
* @author James.Dodd
* @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
* @deprecated This class is all kinds of wonky; use ReferenceMap instead.
* @see <A HREF="http://issues.apache.org/bugzilla/show_bug.cgi?id=9571">
* Bug#9571</A>
*/
public class SoftRefHashMap implements Map {
/** The wrapped HashMap */
private Map hashMap = new HashMap();
public SoftRefHashMap() {
}
/**
* Removes References that have had their referents garbage collected
*/
public void purge() {
Map map = getMap();
Set keys = map.keySet();
if ( keys == null ) {
return;
}
for ( Iterator i = keys.iterator(); i.hasNext(); ) {
Object key = (Object) i.next();
Reference ref = (Reference) map.get( key );
if ( ref.get() == null ) {
map.remove( key );
}
}
}
// Map implementation
// -------------------------------------------------------
/**
* Retrieves the referent of the Referenced value
* @param key The key with which to retrieve the value
*/
public Object get( final Object key ) {
Reference ref = (Reference) getMap().get( key );
if ( ref == null ) {
return null;
}
return ref.get();
}
/**
* Adds a key-value mapping, wrapping the value in a Reference
*/
public Object put( final Object key, final Object value ) {
Object answer = getMap().put( key, createReference( value ) );
if ( answer != null ) {
return ((Reference) answer).get();
}
return null;
}
/**
* Returns a collection of the Referenced values
*/
public Collection values() {
Set wrappedValues = (Set) getMap().values();
Set values = new TreeSet();
if ( wrappedValues == null ) {
return values;
}
for ( Iterator i = wrappedValues.iterator(); i.hasNext(); ) {
Reference ref = (Reference) i.next();
if ( ref != null ) {
values.add( ref.get() );
}
}
return values;
}
/**
* Answers whether the argument is in the domain of the mappings
*/
public boolean containsKey( Object key ) {
return getMap().containsKey( key );
}
/**
* Answers whether the argument is a Referenced value
*/
public boolean containsValue( Object value ) {
Collection values = (Collection) getMap().values();
if ( values == null ) {
return false;
}
for ( Iterator i = values.iterator(); i.hasNext(); ) {
Reference ref = (Reference) i.next();
if ( ref == null ) {
continue;
}
Object target = ref.get();
if ( target == value ) {
return true;
}
}
return false;
}
/**
* Put all of the mappings in the argument into this wrapped map
*/
public void putAll( final java.util.Map map ) {
if ( map == null || map.size() == 0 ) {
return;
}
for ( Iterator i = map.keySet().iterator(); i.hasNext(); ) {
Object key = (Object) i.next();
put( key, map.get( key ) );
}
}
/**
* Returns a set view of the mappings in the wrapped map
*/
public Set entrySet() {
Set entries = new HashSet();
if ( size() == 0 ) {
return entries;
}
for ( Iterator i = keySet().iterator(); i.hasNext(); ) {
Object key = i.next();
Object value = get( key );
Entry entry = new Entry( key, value );
entries.add( entry );
}
return entries;
}
/**
* Removes a mapping from this map
*/
public Object remove( final Object key ) {
Reference ref = (Reference) getMap().remove( key );
if ( ref != null ) {
return ref.get();
}
return null;
}
/**
* Clears all mappings
*/
public void clear() {
getMap().clear();
}
/**
* Calculates the hash code for this map
*/
public int hashCode() {
return getMap().hashCode();
}
/**
* Returns the domain of the mappings
*/
public Set keySet() {
return getMap().keySet();
}
/**
* Answers whether there are any mappings
*/
public boolean isEmpty() {
return getMap().isEmpty();
}
/**
* Answers whether this map and the argument are 'the same'
*/
public boolean equals( final Object object ) {
return getMap().equals( object );
}
/**
* Returns the number of mappings in this map
*/
public int size() {
return getMap().size();
}
// Inner Classes
// ---------------------------------------------------------------------
/**
* A map entry, which is backed by this RefHashMap
*/
class Entry implements Map.Entry {
/**
* Constructor
*/
public Entry( Object key, Object value ) {
this.key = key;
this.value = value;
}
// Map.Entry interface
// -----------------------------------------------------------
/**
* Retrieves the key of this mapping
*/
public Object getKey() {
return key;
}
/**
* Retrieves the value of this mapping
*/
public Object getValue() {
return value;
}
/**
* Sets the value of this mapping
*/
public Object setValue( Object value ) {
this.value = value;
put( key, value );
return value;
}
/**
* Return the hash code of this mapping.
* This algorithm was taken from the JavaDoc for Map.Entry
*/
public int hashCode() {
return ( getKey() == null ? 0 : getKey().hashCode() ) ^
( getValue() == null ? 0 : getValue().hashCode() );
}
/** The domain of this mapping */
private Object key;
/** The range of this mapping */
private Object value;
}
/**
* Returns a reference to the argument.
* Override this method to make wrapped maps for other Reference types
*/
protected Reference createReference( Object referent ) {
return new SoftReference( referent );
}
/**
* Retrieves the wrapped HashMap
* @return The wrapped HashMap
*/
protected Map getMap() {
return hashMap;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -