@Override public final int size() { if(isEmpty()) { return 0; } else if(offset < end) { return end - offset; } else { return capacity + end - offset; } }
@Override public E get(final int i) { if(isEmpty()) { throw new IndexOutOfBoundsException(); } return array[translateIndex(i)]; }
@Override public E set(final int i, final E e) { if(isEmpty()) { throw new IndexOutOfBoundsException(Integer.toString(i)); } final int j = translateIndex(i); final E prev = array[j]; array[j] = e; return prev; }
@Override public final E remove(final int i) { if(isEmpty()) { throw new IndexOutOfBoundsException(Integer.toString(i)); } final E e; if(size() == 1) { e = array[offset]; clear(); } else { final int j = translateIndex(i); e = array[j]; if(j == offset) { offset = increaseIndex(offset, 1); } else if(end > 0 && j == end - 1) { end --; } else if(end == 0 && j == capacity - 1) { end = capacity - 1; } else { throw new UnsupportedOperationException("Able to remove only from the beginning either end"); } } return e; }
@Override public final boolean add(final E e) { if(isEmpty()) { array[offset] = e; end = increaseIndex(offset, 1); return true; } else if(size() < capacity) { array[end] = e; end = increaseIndex(end, 1); return true; } else { return false; } }
@Override public final boolean addAll(final Collection<? extends E> elements) { final int elementsCount = elements.size(); if(capacity - size() < elementsCount) { return false; } else { for(final E e: elements) { if(isEmpty()) { array[offset] = e; end = increaseIndex(offset, 1); } else if(size() < capacity) { array[end] = e; end = increaseIndex(end, 1); } } return true; } }