net.sf.javagimmicks.collections.LinkedRing Maven / Gradle / Ivy
package net.sf.javagimmicks.collections;
import java.util.NoSuchElementException;
/**
* An implementation of {@link Ring} that internally operates on a double-linked
* list implementation basis.
*/
public class LinkedRing extends AbstractRing
{
private int _size = 0;
private RingElement _hook = null;
@Override
public int size()
{
return _size;
}
@Override
public RingCursor cursor()
{
return new LinkedRingCursor(this, _hook);
}
private static class RingElement
{
private RingElement _previous;
private RingElement _next;
private E _value;
}
private static class LinkedRingCursor extends BasicRingCursor>
{
private RingElement _current;
private LinkedRingCursor(final LinkedRing ring, final RingElement current)
{
super(ring);
_current = current;
}
@Override
public E get()
{
if (_current == null)
{
throw new NoSuchElementException("Ring is empty");
}
return _current._value;
}
@Override
public void insertAfter(final E value)
{
final RingElement next = _current != null ? _current._next : null;
insert(value, _current, next);
}
@Override
public void insertBefore(final E value)
{
final RingElement previous = _current != null ? _current._previous : null;
insert(value, previous, _current);
}
@Override
public E next()
{
checkForModification();
if (_current == null)
{
throw new NoSuchElementException("Ring is empty");
}
_current = _current._next;
return get();
}
@Override
public E previous()
{
checkForModification();
if (_current == null)
{
throw new NoSuchElementException("Ring is empty");
}
_current = _current._previous;
return get();
}
@Override
public E remove()
{
checkForModification();
// Get the ring size
final int ringSize = _ring._size;
// If nothing to remove, throw an exception
if (ringSize == 0)
{
throw new NoSuchElementException();
}
final E result = _current._value;
if (ringSize == 1)
{
// If only one element is remaining, clean up everything
_current._next = null;
_current._previous = null;
_current = null;
_ring._hook = null;
}
else
{
// Get the next and previous element
final RingElement nextElement = _current._next;
final RingElement previousElement = _current._previous;
// Re-assign their links
nextElement._previous = previousElement;
previousElement._next = nextElement;
// Clean links of element to remove
_current._next = null;
_current._previous = null;
// Relink the hook (if necessary) and the current RingCursor
// position
if (_ring._hook == _current)
{
_ring._hook = nextElement;
}
_current = nextElement;
}
// Decrease ring size
--_ring._size;
// Update modification counters
++_ring._modCount;
++_expectedModCount;
return result;
}
@Override
public RingCursor cursor()
{
return new LinkedRingCursor(_ring, _current);
}
private void insert(final E value, final RingElement previous, final RingElement next)
{
checkForModification();
// Create the new element and set it's value
final RingElement newElement = new RingElement();
newElement._value = value;
if (previous == null || next == null)
{
// This is the first element, so link it to itself
newElement._previous = newElement;
newElement._next = newElement;
// Also update the current element and the hook of the ring
_current = newElement;
_ring._hook = newElement;
}
else
{
// Set links of new element
newElement._previous = previous;
newElement._next = next;
// Set links to new element
previous._next = newElement;
next._previous = newElement;
}
// Increase ring size
++_ring._size;
// Update modification counters
++_ring._modCount;
++_expectedModCount;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy