All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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 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 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();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy