Version 1 had quite a few problems that i didnt think about. A lot of them were pointed out in the replies. I tried to correct them as best as i could to make this code.
However , I'm having some doubts regarding what to do while implementing the Collection interface. Mainly in that if i implement Collection
, a lot of the methods in it are similar to what i'v already coded up. like add()
vs enqueue()
. In such cases , i suppose the best way out will be to make my methods private , and call them from inside their respective Collection implementations ?
Also, I was using System.arraycopy() previously , but in my tests , i found that it wasnt ideal for a circular array. Case in point :
adding : e
head : 5 tail : 5 , size : 12
a b c d e f g h i j k l
adding : f
resizing array to size: 24
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at ResizingCircularArray.resize(ResizingCircularArray.java:16)
at ResizingCircularArray.enqueue(ResizingCircularArray.java:33)
at ResizingCircularArray.main(ResizingCircularArray.java:105)
This came up because : head + size > source length , and resulted in IndexOutOfBounds
exception. So i made something similar that works with cicular array.
// Modified version of System.arraycopy() to work with circular array.
private void arrayCopy(E[] srcArr , int srcpos , E[] destArr , int destpos , int length){
for(int index = 0 ; index < length ; index++){
destArr[index] = srcArr[head++];
if(head == srcArr.length){
head = (head % srcArr.length);
}
}
}
However , I'm unsure as to how to include exceptions for ArrayStore in here . docs say that it throws the exception when passed object is not an array. But how do i check for an array ? The instaceof
checks for one particular type , like int or String , but mine is generic. A bit confused here.
If i could get some suggestions and help regarding the above problems , and my code in general , would be a big help.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class ResizingCircularArray<E> {
private int head = 0;
private int tail = 0;
private int size = 0; // a measure of non-null elements in the array
private E[] arr;
// Modified version of System.arraycopy() to work with circular array.
private void arrayCopy(E[] srcArr , int srcpos , E[] destArr , int destpos , int length){
for(int index = 0 ; index < length ; index++){
destArr[index] = srcArr[head++];
if(head == srcArr.length){
head = (head % srcArr.length);
}
}
}
private void resize() {
System.out.println("resizing array to size: " + 2 * size);
@SuppressWarnings("unchecked")
E[] tempArr = (E[]) new Object[2 * size];
arrayCopy(arr, head, tempArr, 0, size);
head = 0;
tail = size; // tail point to where the NEXT element will land
arr = tempArr;
}
@SuppressWarnings("unchecked")
public ResizingCircularArray() {
arr = (E[]) new Object[3];
}
public void enqueue(E item) {
if (item == null)
throw new NullPointerException(
" adding null values is not allowed ");
if (size == arr.length) {
resize();
}
if (tail == arr.length) {
// going round
tail = (tail % arr.length);
}
arr[tail++] = item;
size++;
System.out.println("head : " + head + " tail : " + tail + " , size : "
+ size);
}
public E dequeue() {
if (!(size > 0))
throw new java.util.NoSuchElementException("size is negative");
E item = arr[head];
arr[head++] = null;
if (head == (arr.length)) {
head = (head % arr.length); // =0
}
--size;
if (size == arr.length / 4) {
resize();
}
System.out.println("head : " + head + " tail : " + tail + " , size : "
+ size);
return item;
}
public boolean isEmpty() {
return size == 0;
}
public E sample(int offset) {
if (offset < 0)
throw new java.lang.IllegalArgumentException(
"provided offset is out of bounds");
return arr[head + offset];
/*
* NOTE : the check for (head+offset)>tail as pointed out by sos will
* work in case of linear array , Not in case of Circular array because
* when tail comes around in a circle , tail will be < than head and the
* above check will create trouble
*/
}
public int size() {
return size;
}
public void display() {
for (E item : arr)
System.out.print(item + " ");
System.out.println("\n");
}
public static void main(String[] args) {
ResizingCircularArray<String> r = new ResizingCircularArray<String>();
String line = null;
String[] segment, parsed;
boolean endFlag = false;
int count = 0;
try (BufferedReader is = new BufferedReader(new FileReader(
"CircArrayPoints.txt"))) {
line = is.readLine();
segment = line.trim().split(";");
System.out.println("total commands : " + segment.length);
for (int i = 0; !segment[i].equals("stop") && !endFlag; i++) {
parsed = segment[i].split(" ");
count++;
switch (parsed[0]) {
case "enq":
System.out.println(count+ ".adding : " + parsed[1]);
r.enqueue(parsed[1]);
r.display();
break;
case "deq":
if (r.isEmpty()) {
System.out.println("Empty queue");
endFlag = true;
break;
}
// print after checking isEmpty() to make sure
// sample(0) doesn't call null etc
System.out.println(count+ ".dequeing : " + r.sample(0));
r.dequeue();
r.display();
break;
case "disp":
r.display();
break;
default:
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Files : CircArrayPoints.txt
enq a;enq b;enq c;enq d;enq e;enq f;enq g;enq h;enq i;enq j;enq k;enq l;deq;deq;deq;deq;deq;enq a;enq b;enq c;enq d;enq e;enq f;enq g;enq h;enq i;enq j;enq k;enq l;enq m;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;deq;disp;stop