gov.sandia.cognition.collection.DefaultIndexer Maven / Gradle / Ivy
/*
* File: DefaultIndexer.java
* Authors: Justin Basilico
* Project: Cognitive Foundry
*
* Copyright 2011 Cognitive Foundry. All rights reserved.
*/
package gov.sandia.cognition.collection;
import gov.sandia.cognition.util.AbstractCloneableSerializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A default implementation of the {@link Indexer} interface that simply maps
* objects to a range from 0 to n-1 in the order they are given. It stores the
* list of objects plus a mapping of values to indices. This implementation is
* not synchronized.
*
* @param The type of the value being indexed. Must have a valid
* equals and hashCode implementation.
* @author Justin Basilico
* @since 3.3.3
* @see Indexer
*/
public class DefaultIndexer
extends AbstractCloneableSerializable
implements Indexer
{
/**
* The list of values, which can be accessed by index.
*/
protected ArrayList valueList;
/**
* The mapping of values to their indices.
*/
protected LinkedHashMap valueToIndexMap;
/**
* Creates a new, empty {@link DefaultIndexer}.
*/
public DefaultIndexer()
{
super();
this.valueList = new ArrayList<>();
this.valueToIndexMap = new LinkedHashMap<>();
}
/**
* Creates a new, empty {@link DefaultIndexer} with the given initial
* capacity.
*
* @param initialCapacity The initial capacity for the indexer. Must be
* positive.
*/
public DefaultIndexer(
final int initialCapacity)
{
super();
this.valueList = new ArrayList<>(initialCapacity);
this.valueToIndexMap = CollectionUtil.createLinkedHashMapWithSize(
initialCapacity);
}
/**
* Creates a new {@link DefaultIndexer} and adds he given collection of
* values to it.
*
* @param values The initial set of values to add to the indexer.
*/
public DefaultIndexer(
final Collection extends ValueType> values)
{
this(values.size());
this.addAll(values);
}
@Override
public DefaultIndexer clone()
{
@SuppressWarnings("unchecked")
final DefaultIndexer clone
= (DefaultIndexer) super.clone();
clone.valueList = new ArrayList<>(this.valueList);
clone.valueToIndexMap = new LinkedHashMap<>(
this.valueToIndexMap);
return clone;
}
@Override
public Integer add(
final ValueType value)
{
Integer result = this.getIndex(value);
if (result == null)
{
result = this.valueList.size();
this.valueList.add(value);
this.valueToIndexMap.put(value, result);
}
return result;
}
@Override
public void addAll(
final Iterable extends ValueType> values)
{
for (ValueType value : values)
{
this.add(value);
}
}
@Override
public Integer getIndex(
final ValueType value)
{
return this.valueToIndexMap.get(value);
}
@Override
public ValueType getValue(
final int index)
{
return this.valueList.get(index);
}
@Override
public ValueType getValue(
final Integer index)
{
return this.valueList.get(index);
}
@Override
public boolean hasValue(
final ValueType value)
{
return this.valueToIndexMap.containsKey(value);
}
@Override
public boolean hasIndex(
final int index)
{
return index >= 0 && index < this.size();
}
@Override
public boolean hasIndex(
final Integer index)
{
return index != null && this.hasIndex(index.intValue());
}
@Override
public boolean isEmpty()
{
return this.valueList.isEmpty();
}
@Override
public int size()
{
return this.valueList.size();
}
@Override
public Set valueSet()
{
return Collections.unmodifiableSet(this.valueToIndexMap.keySet());
}
@Override
public List valueList()
{
return Collections.unmodifiableList(this.valueList);
}
@Override
public Map asMap()
{
return Collections.unmodifiableMap(this.valueToIndexMap);
}
@Override
public void clear()
{
valueList.clear();
valueToIndexMap.clear();
}
}