Circular buffer implementation for buffering TCP socket messages I have written my own for practice and also some tweaks for my specific requirement.  There is an insert which can copy a range (well array copy really) which I am hoping is more efficient than individual element insert.

Can anyone make any comments specifically as regards efficiency and code elegance.  I need to use this with Java 1.6 and am getting a warning on the array = newArray(size); line in the constructor.  But that is the only issue I am currently aware of.

import java.util.Arrays;  //copyOf

public class CircularBuffer&lt;T&gt; {
    private T[] array;  //storage
    private int put_idx, get_idx, count; //get/put &amp; internal num elements counter
    private final int size;   //size of internal array storage

    public CircularBuffer(int size) {
        get_idx = 0;
        put_idx = 0;
        count   = 0;
        this.size = size;

        //Type safety: A generic array of T is created for a varargs parameter - investigate how to remove warning
        array = newArray(size); 
    }

    //@SafeVarargs - ok in java 1.7
    static &lt;T&gt; T[] newArray(int length, T... array)
    {
        return Arrays.copyOf(array, length);
    }    

    void reset(){
        get_idx=put_idx=count=0;
    }

    public boolean empty() { return count == 0; }

    public boolean full() { return count == size; }


    int get_count() { return count; }

    //inserts a single new element
    public void insert(T element)
    {
        if(full())
            throw new ArrayIndexOutOfBoundsException("buffer full");

        array[put_idx++] = element;
        put_idx %= size;
        ++count;
    }

    //insert array of specified length
    public void insert(T[] thearray) {
        if(thearray.length + count &gt; size)
            throw new ArrayIndexOutOfBoundsException("insufficient space to insert array");     

        //first copy to end - contiguous array copy
        int remaining = size - put_idx;
        if(remaining &gt;= thearray.length) {
            System.arraycopy(thearray, 0, array, put_idx, thearray.length);
            put_idx += thearray.length;
            put_idx %= size;
        } else {
            System.arraycopy(thearray, 0, array, put_idx, remaining);
            int rest = thearray.length - remaining;
            System.arraycopy(thearray, remaining, array, 0, rest);
            put_idx = rest;
        }
        count += thearray.length;
    }

    //get the oldest element, move read pointer
    public T get()
    {
        if(empty())
            throw new ArrayIndexOutOfBoundsException("buffer empty");

        final T ret = array[get_idx++];
        get_idx %= size;
        --count;
        return ret;
    }  
}


Code to exercise class:

public class TestCircularBuffer {
    static public void main(String args[]) {
        new TestCircularBuffer().go();
    }

    void go() {
        int SIZE = 1000;
        int arr[] = new int[SIZE];

        for(int i = 0; i &lt; SIZE; ++i) {
            arr[i] = i;
        }

        CircularBuffer&lt;Integer&gt; cb = new CircularBuffer&lt;Integer&gt;(10);

        //exercise circ buffer
        int i = 0;
        while(i &lt; SIZE) {
            while(!cb.full())
                cb.insert(arr[i++]);

            while(!cb.empty())
                System.out.print(cb.get() + " ");
        }

        //now exercise array insert
        System.out.println("\nrange insert test");
        Integer marr[] = {1,2,3,4};

        i = 0;
        while(i &lt; 20) {
            //will only be able to fit 2 lots
            cb.insert(marr);
            cb.insert(marr);

            while(!cb.empty())
                System.out.print(cb.get() + " ");

            ++i;
        }
    }
}
A few minor notes:


Comments like the following are unnecessary:

private T[] array; // storage


You could call the field as storage and remove the comment.
A "solution" for the warning in the constructor:

@SuppressWarnings("unchecked")
private T[] newArray(int length) {
    return (T[]) new Object[length];
}


Reference: Java how to: Generic Array creation
camelCase variable and method names are more common in Java than underscored ones. (Code Conventions for the Java Programming Language, 9 - Naming Conventions)
From Code Complete, 2nd Edition, p761:


  Use only one data declaration per line
  
  [...] 
  
  It’s easier to modify declarations because each declaration is self-contained.
  
  [...]
  
  It’s easier to find specific variables because you can scan a single
  column rather than reading each line. It’s easier to find and fix
  syntax errors because the line number the compiler gives you has 
  only one declaration on it.

Setting default integer field values to zero is unnecessary in the constructor since zero is the default int value:

getIdx = 0;
putIdx = 0;
count = 0;

Does it make sense to create a CircularBuffer instance with zero size? If not check it and throw an IllegalArgumentException in the constructor.
The second insert method might be a premature optimization. 
I'd throw IllegalStateException instead of ArrayIndexOutOfBoundsException. The clients of the class should not know that it uses an array (or anything else) for storage.
Here are a few unit tests:

@Test(expected = IllegalArgumentException.class)
public void testZeroSize() {
    new CircularBuffer&lt;String&gt;(0);
}

@Test
public void testIsEmptyOnNewBuffer() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    assertTrue(buffer.isEmpty());
}

@Test
public void testIsFullOnNewBuffer() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    assertFalse(buffer.isFull());
}

@Test
public void testIsEmpty() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    assertFalse(buffer.isEmpty());
}

@Test
public void testIsFull() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.insert("b");
    buffer.insert("c");
    assertTrue(buffer.isFull());
}

@Test
public void testIsEmptyAfterReset() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.reset();
    assertTrue(buffer.isEmpty());
}

@Test
public void testIsFullAfterReset() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.insert("b");
    buffer.insert("c");
    buffer.reset();
    assertFalse(buffer.isFull());
}

@Test
public void testIsEmptyOnUsedBuffer() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.insert("b");
    buffer.insert("c");

    assertFalse("isEmpty 1", buffer.isEmpty());
    buffer.get();
    assertFalse("isEmpty 2", buffer.isEmpty());
    buffer.get();
    assertFalse("isEmpty 3", buffer.isEmpty());
    buffer.get();
    assertTrue("isEmpty 4", buffer.isEmpty());
}

@Test
public void testIsFullOnUsedBuffer() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.insert("b");
    buffer.insert("c");
    buffer.get();

    assertFalse("isFull 1", buffer.isFull());
    buffer.get();
    assertFalse("isFull 2", buffer.isFull());
    buffer.get();
    assertFalse("isFull 3", buffer.isFull());
}

@Test
public void testInsert() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.insert("b");
    buffer.insert("c");
}

@Test(expected = IllegalStateException.class)
public void testInsertFull() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.insert("b");
    buffer.insert("c");
    buffer.insert("d");
}

@Test(expected = IllegalStateException.class)
public void testGetOnEmptyBuffer() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.get();
}

@Test(expected = IllegalStateException.class)
public void testGetOnEmptyUsedBuffer() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.get();

    buffer.get();
}

@Test
public void testGet() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    assertEquals("a", buffer.get());
    buffer.insert("b");
    buffer.insert("c");
}

@Test
public void testDelayedGet() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.insert("b");
    buffer.insert("c");
    assertEquals("a", buffer.get());
}

@Test
public void testInsertAndGetTwice() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    buffer.insert("b");
    buffer.insert("c");
    assertEquals("a", buffer.get());
    assertEquals("b", buffer.get());
    assertEquals("c", buffer.get());

    buffer.insert("d");
    buffer.insert("e");
    buffer.insert("f");
    assertEquals("d", buffer.get());
    assertEquals("e", buffer.get());
    assertEquals("f", buffer.get());
}

@Test
public void testGetAndInsert() {
    final CircularBuffer&lt;String&gt; buffer = new CircularBuffer&lt;String&gt;(3);
    buffer.insert("a");
    assertEquals("a", buffer.get());

    buffer.insert("b");
    assertEquals("b", buffer.get());

    buffer.insert("c");
    assertEquals("c", buffer.get());

    buffer.insert("d");
    buffer.insert("e");
    assertEquals("d", buffer.get());
    assertEquals("e", buffer.get());

    buffer.insert("f");
    assertEquals("f", buffer.get());

    assertTrue("empty", buffer.isEmpty());
}


(I've renamed a few methods.)