/* Copyright (C) 2006 EBI This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the itmplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.biomart.common.utils; import java.io.Serializable; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * Handles list backed maps. * * @author Richard Holland <holland@ebi.ac.uk> * @version $Revision: 1.1 $, $Date: 2007-11-09 11:36:28 $, modified by * $Author: rh4 $ * @since 0.7 */ public class ListBackedMap extends AbstractMap implements Serializable { private static final long serialVersionUID = 1L; private final List keys = new ArrayList(); private final List values = new ArrayList(); /** * Construct a new list backed map. Keys will be returned in the order they * were added. */ public ListBackedMap() { super(); } /** * Construct a new list backed map. Keys will be returned in the order they * were added. * * @param map * a set of initial entries, to be added in the order returned by * the {@link Map#entrySet()} iterator. */ public ListBackedMap(final Map map) { super(); this.putAll(map); } public Set entrySet() { return new AbstractSet() { public Iterator iterator() { return new Iterator() { private int i = -1; public boolean hasNext() { return this.i < size() - 1; } public Object next() { ++i; return new Map.Entry() { public Object getKey() { return ListBackedMap.this.keys.get(i); } public Object getValue() { return ListBackedMap.this.values.get(i); } public Object setValue(final Object value) { return ListBackedMap.this.values.set(i, value); } }; } public void remove() { ListBackedMap.this.keys.remove(this.i); ListBackedMap.this.values.remove(this.i); } }; } public int size() { return ListBackedMap.this.keys.size(); } }; } public Object put(final Object key, final Object value) { if (this.keys.contains(key)) // Replace. return this.values.set(this.keys.indexOf(key), value); else { // Append. this.keys.add(key); this.values.add(value); return value; } } /** * Inserts the key after the previousKey, or at the beginning of the map if * previousKey is null. Otherwise, see {@link #put(Object, Object)}. * * @param previousKey * the previousKey to insert after. * @param key * the key to insert. * @param value * the value to insert. * @return the previous value for that key, if any. */ public Object put(final Object previousKey, final Object key, final Object value) { // Remove existing if exists. Object returnObj = null; final int existingIndex = this.keys.indexOf(key); if (existingIndex >= 0) { this.keys.remove(existingIndex); returnObj = this.values.remove(existingIndex); } if (previousKey == null) { // Prepend. this.keys.add(0, key); this.values.add(0, value); } else { // Insert. final int index = this.keys.indexOf(previousKey) + 1; this.keys.add(index, key); this.values.add(index, value); } return returnObj; } }