net.museful.general.CircularArrayList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openterm Show documentation
Show all versions of openterm Show documentation
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;
}
}