📄 onetomanymap.java
字号:
/*****************************************************************************
* Source code information
* -----------------------
* Original author Ian Dickinson, HP Labs Bristol
* Author email Ian.Dickinson@hp.com
* Package Jena
* Created 5 Jan 2001
* Filename $RCSfile: OneToManyMap.java,v $
* Revision $Revision: 1.14 $
* Release status Preview-release $State: Exp $
*
* Last modified on $Date: 2007/01/02 11:52:14 $
* by $Author: andy_seaborne $
*
* (c) Copyright 2001, 2002, 2002, 2003, 2004, 2005, 2006, 2007 Hewlett-Packard Development Company, LP
* See end of file for details
*****************************************************************************/
// Package
///////////////
package com.hp.hpl.jena.util;
// Imports
///////////////
import java.util.*;
import com.hp.hpl.jena.util.iterator.NullIterator;
/**
* An extension to a standard map that supports one-to-many mappings: that is, there
* may be zero, one or many values corresponding to a given key.
*
* @author Ian Dickinson, HP Labs (<a href="mailto:Ian.Dickinson@hp.com">email</a>)
* @version CVS info: $Id: OneToManyMap.java,v 1.14 2007/01/02 11:52:14 andy_seaborne Exp $
*/
public class OneToManyMap
implements Map
{
// Constants
//////////////////////////////////
// Static variables
//////////////////////////////////
// Instance variables
//////////////////////////////////
/** Encapsulated hash table stores the values */
private Map m_table = new HashMap();
// Constructors
//////////////////////////////////
/**
* <p>Construct a new empty one-to-many map</p>
*/
public OneToManyMap() {
}
/**
* <p>Construct a new one-to-many map whose contents are
* initialised from the existing map.</p>
*
* @param map An existing one-to-many map
*/
public OneToManyMap( OneToManyMap map ) {
// copy the contents of the existing map
// note we can't just use the copying constructor for hashmap
// as we don't want to share the arraylists that are the key values
for (Iterator i = map.keySet().iterator(); i.hasNext(); ) {
Object key = i.next();
for (Iterator j = map.getAll( key ); j.hasNext(); ) {
put( key, j.next() );
}
}
}
// External signature methods
//////////////////////////////////
/**
* Clear all entries from the map.
*/
public void clear() {
m_table.clear();
}
/**
* Answer true if the map contains the given value as a key.
*
* @param key The key object to test for
* @return True or false
*/
public boolean containsKey( Object key ) {
return m_table.containsKey( key );
}
/**
* Answer true if the map contains the given object as a value
* stored against any key. Note that this is quite an expensive
* operation in the current implementation.
*
* @param value The value to test for
* @return True if the value is in the map
*/
public boolean containsValue( Object value ) {
for (Iterator values = m_table.values().iterator(); values.hasNext(); ) {
Object x = values.next();
if (x.equals( value )) {
return true;
}
else if (x instanceof List && ((List) x).contains( value )) {
return true;
}
}
return false;
}
/**
* <p>Answer true if this mapping contains the pair
* <code>(key, value)</code>.</p>
* @param key A key object
* @param value A value object
* @return True if <code>key</code> has <code>value</code>
* as one of its values in this mapping
*/
public boolean contains( Object key, Object value ) {
for (Iterator i = getAll( key ); i.hasNext(); ) {
if (i.next().equals( value )) {
return true;
}
}
return false;
}
/**
* Answer a set of the mappings in this map. Each member of the set will
* be a Map.Entry value.
*
* @return A Set of the mappings as Map.Entry values.
*/
public Set entrySet() {
Set s = CollectionFactory.createHashedSet();
for (Iterator e0 = m_table.keySet().iterator(); e0.hasNext(); ) {
Object key = e0.next();
List values = (List) m_table.get( key );
// add each key-value pair to the result set
for (ListIterator e1 = values.listIterator(); e1.hasNext(); ) {
s.add( new Entry( key, e1.next() ) );
}
}
return s;
}
/**
* Compares the specified object with this map for equality.
* Returns true if the given object is also a map and the two Maps
* represent the same mappings. More formally, two maps t1 and t2 represent
* the same mappings if t1.entrySet().equals(t2.entrySet()).
*
* This ensures that the equals method works properly across different
* implementations of the Map interface.
*
* @param o The object to be compared for equality with this map.
* @return True if the specified object is equal to this map.
*/
public boolean equals( Object o ) {
if (o instanceof java.util.Map) {
return entrySet().equals( ((Map) o).entrySet() );
}
else
return false;
}
/**
* Get a value for this key. Since this map is explicitly designed to
* allow there to be more than one mapping per key, this method will return
* an undetermined instance of the mapping. If no mapping exists, or the
* selected value is null, null is returned.
*
* @param key The key to access the map.
* @return One of the values this key corresponds to, or null.
* @see #getAll
*/
public Object get( Object key ) {
ArrayList entry = (ArrayList) m_table.get( key );
if (entry != null) {
if (!entry.isEmpty()) {
return entry.get( 0 );
}
}
// not present
return null;
}
/**
* Answer an iterator over all of the values for the given key. An iterator
* is always supplied, even if the key is not present.
*
* @param key The key object
* @return An iterator over all of the values for this key in the map
*/
public Iterator getAll( Object key ) {
ArrayList entry = (ArrayList) m_table.get( key );
return (entry != null) ? entry.iterator() : NullIterator.instance;
}
/**
* Returns the hash code value for this map. The hash code of a map is
* defined to be the sum of the hashCodes of each entry in the map's
* entrySet view. This ensures that t1.equals(t2) implies
* that t1.hashCode()==t2.hashCode() for any two maps t1 and t2,
* as required by the general contract of Object.hashCode
*/
public int hashCode() {
int hc = 0;
for (Iterator i = entrySet().iterator(); i.hasNext(); ) {
hc ^= i.next().hashCode();
}
return hc;
}
/**
* Answer true if the map is empty of key-value mappings.
*
* @return True if there are no entries.
*/
public boolean isEmpty() {
return m_table.isEmpty();
}
/**
* Answer a set of the keys in this map
*
* @return The keys of the map as a Set
*/
public Set keySet() {
return m_table.keySet();
}
/**
* Associates the given value with the given key. Since this map formulation
* allows many values for one key, previous associations with the key are not
* lost. Consequently, the method always returns null (since the replaced value
* is not defined).
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -