at.spardat.xma.mdl.util.KeyedList Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
// @(#) $Id: KeyedList.java 2089 2007-11-28 13:56:13Z s3460 $
package at.spardat.xma.mdl.util;
import java.util.*;
/**
* This class realizes a ordered collection consisting of entries (key, value).
* The keys are Strings. The collection has set semantics, i.e., at most one
* entry with a particular key is allowed. Nevertheless, the collection is
* ordered. The order is controlled via positional insertion
* operations (method add providing an index).
*
* You may view this class as a mix of HashMap and ArrayList,
* gaining the fast access by key of the HashMap and retaining the order
* and the ease of indexed access of the ArrayList.
*
* @author YSD, 09.04.2003 14:10:02
*/
public class KeyedList implements Cloneable {
/**
* Appends the specified element to the end of this list.
*
* @param key the key of the element; must not be null
* @param value the value associated with the key
* @return true if successfully added, false if entry with key already in the list.
*/
public boolean add (String key, Object value) {
if (key == null) throw new IllegalArgumentException();
if (hash_.containsKey(key)) return false;
list_.add(key);
hash_.put(key, value);
return true;
}
/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted.
* @param key the key of the element; must not be null
* @param value the value associated with the key
* @return true if entry has been successfully added to the list, false
* if this list already contained an entry with the provided key.
* @exception ArrayIndexOutOfBoundsException if index is out of range
* (index < 0 || index > size()).
*/
public boolean add (int index, String key, Object value) {
if (key == null) throw new IllegalArgumentException();
if (hash_.containsKey(key)) return false;
list_.add(index, key);
hash_.put(key, value);
return true;
}
/**
* Returns the key for the entry at the provided index.
*
* @param index index at which to return the key.
* @exception ArrayIndexOutOfBoundsException if index out of range.
*/
public String getKey (int index) {
return (String) list_.get(index);
}
/**
* Returns the value of the entry at the provided index.
*
* @param index index at which to return the value.
* @exception IndexOutOfBoundsException if index out of range.
*/
public Object getValue (int index) {
String key = (String) list_.get(index);
return hash_.get(key);
}
/**
* Returns the value for the provided key or null if
* this list does not contain an entry with the specified key.
*
* @param key the key whose value is to be found.
* @return the found value or null if this list does
* not contain an entry with the provided key.
*/
public Object getValue (String key) {
return hash_.get(key);
}
/**
* Returns the index of the entry whose key equals the one provided.
*
* This is a time consuming operation of O(n).
*
* @param key the key of the entry whose index is wanted.
* @return the index of the found entry or -1 if the key is not
* in the list.
*/
public int indexOf (String key) {
if (key == null) return -1;
for (int i=list_.size()-1; i>=0; i--) {
if (key.equals(list_.get(i))) {
return i;
}
}
return -1;
}
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
*/
public void clear() {
list_.clear();
hash_.clear();
}
/**
* Returns true if this list contains a element with the specified key.
*
* @param key the key to check for existence
*/
public boolean containsKey (String key) {
return hash_.containsKey(key);
}
/**
* Removes the entry with the provided key.
*
* Removing is a time consuming operation and requires O(n).
*
* @param key identifies the entry to be removed
* @return true if the entry was found and has been removed, false otherwise.
*/
public boolean remove (String key) {
if (!hash_.containsKey(key)) return false;
int index = indexOf (key);
if (index == -1) return false;
remove (index);
return true;
}
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* Removing is a time consuming operation requiring O(n). Removing
* from the end of the list requires O(1).
*
* @param index the index of the element to removed.
* @return the key of the element that was removed from the list.
* @throws IndexOutOfBoundsException if index out of range (index
* < 0 || index >= size()).
*/
public String remove (int index) {
String key = (String) list_.get (index);
hash_.remove(key);
list_.remove(index);
return key;
}
/**
* Replaces the old value associated with the provided key with a new one.
*
* @param key the key whose value is to be replaced
* @param value the new value
* @return true if this list contained the provided key and the replace
* has been done, false otherwise.
*/
public boolean replace (String key, Object value) {
if (!hash_.containsKey(key)) return false;
hash_.put(key, value);
return true;
}
/**
* Returns the size of this list.
*
* @return the size
*/
public int size() {
return list_.size();
}
/**
* Clones shallow. The contained keys and values are not cloned. With keys it
* does not matter, since they are immutable. If the values are also immutable,
* you need not worry about shallow and deep semantics at all.
*
* @see java.lang.Object#clone()
*/
public Object clone() {
KeyedList l = null;
try {
l = (KeyedList) super.clone();
l.list_ = (ArrayList) list_.clone();
l.hash_ = (HashMap) hash_.clone();
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
return l;
}
/**
* @see java.lang.Object#toString()
*/
public String toString () {
StringBuffer b = new StringBuffer();
for (int i=0, len=size(); i0) b.append(',');
b.append('[');
b.append(getKey(i)); b.append(','); b.append(String.valueOf(getValue(i)));
b.append(']');
}
return b.toString();
}
// contains Entry-objects
private ArrayList list_ = new ArrayList ();
// keys are Strings, values are Entry-objects
private HashMap hash_ = new HashMap ();
}