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

net.museful.general.CircularArrayList Maven / Gradle / Ivy

Go to download

An open source emulator supporting 3270 and potentially later 5250 terminal types.

The newest version!
/**
 * Reputedly more efficient for head removals:
 *
 *
 */
package net.museful.general;

import java.util.*;

/**
 * If you use this code, please consider notifying isak at du-preez dot com with a brief description of your application.
 *
 * This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or
 * distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any
 * means.
 */
public class CircularArrayList
    extends AbstractList implements RandomAccess
{

    private final int n; // buffer length
    private final List buf; // a List implementing RandomAccess
    private int head = 0;
    private int tail = 0;

    public CircularArrayList(int capacity)
    {
        n = capacity + 1;
        buf = new ArrayList(Collections.nCopies(n, (E) null));
    }

    public int capacity()
    {
        return n - 1;
    }

    private int wrapIndex(int i)
    {
        int m = i % n;
        if (m < 0)
        { // java modulus can be negative
            m += n;
        }
        return m;
    }

    // This method is O(n) but will never be called if the
    // CircularArrayList is used in its typical/intended role.
    private void shiftBlock(int startIndex, int endIndex)
    {
        assert (endIndex > startIndex);
        for (int i = endIndex - 1; i >= startIndex; i--)
        {
            set(i + 1, get(i));
        }
    }

    @Override
    public int size()
    {
        return tail - head + (tail < head ? n : 0);
    }

    @Override
    public E get(int i)
    {
        if (i < 0 || i >= size())
        {
            throw new IndexOutOfBoundsException();
        }
        return buf.get(wrapIndex(head + i));
    }

    @Override
    public E set(int i, E e)
    {
        if (i < 0 || i >= size())
        {
            throw new IndexOutOfBoundsException();
        }
        return buf.set(wrapIndex(head + i), e);
    }

    @Override
    public void add(int i, E e)
    {
        int s = size();
        if (s == n - 1)
        {
            throw new IllegalStateException(
                "CircularArrayList is filled to capacity. "
                    + "(You may want to remove from front"
                    + " before adding more to back.)");
        }
        if (i < 0 || i > s)
        {
            throw new IndexOutOfBoundsException();
        }
        tail = wrapIndex(tail + 1);
        if (i < s)
        {
            shiftBlock(i, s);
        }
        set(i, e);
    }

    @Override
    public E remove(int i)
    {
        int s = size();
        if (i < 0 || i >= s)
        {
            throw new IndexOutOfBoundsException();
        }
        E e = get(i);
        if (i > 0)
        {
            shiftBlock(0, i);
        }
        head = wrapIndex(head + 1);
        return e;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy