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

gov.sandia.cognition.collection.RangeExcludedArrayList Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * File:                RangeExcludedArrayList.java
 * Authors:             Justin Basilico
 * Company:             Sandia National Laboratories
 * Project:             Cognitive Foundry
 *
 * Copyright September 26, 2007, Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
 * or on behalf of the U.S. Government. Export of this program may require a
 * license from the United States Government. See CopyrightHistory.txt for
 * complete details.
 *
 */

package gov.sandia.cognition.collection;

import gov.sandia.cognition.annotation.CodeReview;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.RandomAccess;

/**
 * The {@code RangeExcludedArrayList} class implements a light-weight list on
 * top of an {@code ArrayList} where a certain range of values is excluded from
 * the list. In some ways, this class is a mirror of the subList method that
 * exists on the {@code ArrayList} class, which is that it gives a list that
 * contains everything, except what is in the sub-list. The implementation
 * creates a read-only collection that remains O(1) for random access.
 *
 * Note: One difference from the subList method is that the both indices given
 * to this list are inclusive, because it makes more sense when excluding a
 * range.
 *
 * @param   The type stored in the collection.
 * @author Justin Basilico
 * @since  2.0
 */
@CodeReview(
    reviewer = "Kevin R. Dixon",
    date = "2008-02-08",
    changesNeeded = false,
    comments =
    {
        "I'm impressed: iteration (foreach) works on this class.  I was ready to flunk this code review, but my unit test passes.",
        "Looks fine."
    }
)
public class RangeExcludedArrayList
    extends AbstractList
    implements RandomAccess, MultiCollection
{

    /** The underlying list. */
    private ArrayList list;

    /** The minimum index to exclude (inclusive). */
    private int fromIndex;

    /** The size excluded. */
    private int sizeExcluded;

    /**
     * Creates a new instance of RangeExcludedArrayList.
     *
     * @param  list The list to apply the range exclusion to.
     * @param  fromIndex The lower index to exclude (inclusive).
     * @param  toIndex The upper index to exclude (inclusive).
     */
    public RangeExcludedArrayList(
        final ArrayList list,
        final int fromIndex,
        final int toIndex)
    {
        if (fromIndex < 0)
        {
            throw new IndexOutOfBoundsException(
                "fromIndex = " + fromIndex);
        }
        else if (toIndex >= list.size())
        {
            throw new IndexOutOfBoundsException(
                "toIndex = " + toIndex);
        }
        else if (fromIndex > toIndex)
        {
            throw new IllegalArgumentException(
                "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
        }

        // Save the data. We save the size exlcuded in order to avoid computing
        // the difference each time.
        this.list = list;
        this.fromIndex = fromIndex;
        this.sizeExcluded = toIndex + 1 - fromIndex;
    }

    public E get(
        final int index)
    {
        if (index < this.fromIndex)
        {
            return this.list.get(index);
        }
        else // ( index >= fromIndex )
        {
            return this.list.get(this.sizeExcluded + index);
        }
    }

    public int size()
    {
        return this.list.size() - this.sizeExcluded;
    }

    public List> subCollections()
    {
        if (this.sizeExcluded <= 0)
        {
            // The result is the whole list.
            return Collections.singletonList(this.list);
        }

        // Create the list to hold the result.
        final ArrayList> result = new ArrayList>(2);

        // Add the first segment, if there is one.
        if (this.fromIndex > 0)
        {
            result.add(this.list.subList(0, this.fromIndex));
        }

        // Add the second segment, if there is one.
        final int toIndex = this.fromIndex + this.sizeExcluded;
        final int listSize = this.list.size();
        if (toIndex < listSize)
        {
            result.add(this.list.subList(toIndex, listSize));
        }

        return result;
    }

    public int getSubCollectionsCount()
    {
        return this.subCollections().size();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy