
org.biojava.utils.OverlayMap Maven / Gradle / Ivy
/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package org.biojava.utils;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
/**
*
* Overlap one map onto another. This allows you to have a map with local values
* and default values. The local and default values are provided by a child and
* parent map.
*
*
* @author Thomas Down
* @author Matthew Pocock
*/
public class OverlayMap extends AbstractMap {
private Map parent;
private Map overlay;
/**
* Build a new map with default key-value pairs.
*
* @param parent the default fall-through Map
* @param overlay the overriding Map
*/
public OverlayMap(Map parent, Map overlay) {
super();
this.parent = parent;
this.overlay = overlay;
}
/**
* Build a new map with default key-value pairs.
*
* @param parent the default fall-through Map
*/
public OverlayMap(Map parent) {
super();
this.parent = parent;
this.overlay = new HashMap();
}
/**
* Return the object containing the fallback mappings.
* This is the actual parent map, not a copy.
*
* @return the parent map
*/
public Map getParentMap() {
return parent;
}
/**
* Return the object containing the overlay mappings.
* This is the actual child map, not a copy.
*
* @return the child map
*/
public Map getOverlayMap() {
return overlay;
}
//
// Basic map operations, done explicitly
//
public Object get(Object key) {
Object value = overlay.get(key);
if (value == null)
value = parent.get(key);
return value;
}
public Set entrySet() {
return new OEntrySet();
}
public Set keySet() {
return new OKeySet();
}
public boolean containsKey(Object key) {
return overlay.containsKey(key) || parent.containsKey(key);
}
public Object put(Object key, Object value) {
Object old = get(key);
overlay.put(key, value);
return old;
}
private class OKeySet extends AbstractSet {
private Set parentKeys;
private OKeySet() {
super();
parentKeys = parent.keySet();
}
public Iterator iterator() {
return new Iterator() {
Iterator oi = overlay.keySet().iterator();
Iterator pi = parentKeys.iterator();
Object peek = null;
public boolean hasNext() {
if (peek == null)
peek = nextObject();
return (peek != null);
}
public Object next() {
if (peek == null) {
peek = nextObject();
}
if (peek == null) {
throw new NoSuchElementException();
}
Object o = peek;
peek = null;
return o;
}
private Object nextObject() {
if (oi.hasNext()) {
return oi.next();
}
Object po = null;
while (po == null && pi.hasNext()) {
po = pi.next();
if (overlay.containsKey(po)) {
po = null;
}
}
return po;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public int size() {
int i = 0;
Iterator keys = iterator();
while(keys.hasNext()) {
keys.next();
++i;
}
return i;
}
public boolean contains(Object o) {
return overlay.containsKey(o) || parentKeys.contains(o);
}
}
private class OEntrySet extends AbstractSet {
OKeySet ks;
private OEntrySet() {
super();
ks = new OKeySet();
}
public Iterator iterator() {
return new Iterator() {
Iterator ksi = ks.iterator();
public boolean hasNext() {
return ksi.hasNext();
}
public Object next() {
Object k = ksi.next();
Object v = get(k);
return new OMapEntry(k, v);
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public int size() {
return ks.size();
}
}
private static class OMapEntry implements Map.Entry {
private Object key;
private Object value;
private OMapEntry(Object key, Object value) {
this.key = key;
this.value = value;
}
public Object getKey() {
return key;
}
public Object getValue() {
return value;
}
public Object setValue(Object v) {
throw new UnsupportedOperationException();
}
public boolean equals(Object o) {
if (! (o instanceof Map.Entry)) {
return false;
}
Map.Entry mo = (Map.Entry) o;
return ((key == null ? mo.getKey() == null : key.equals(mo.getKey())) &&
(value == null ? mo.getValue() == null : value.equals(mo.getValue())));
}
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy