我有一个循环数组队列的代码,代码有很多解释工作的注释。
import java.util.NoSuchElementException;
public class CircularArrayQueue implements MyQueue{
private int front, rear, count;
private int[] queue;
private int capacity = 1000;
public CircularArrayQueue() {
front = rear = count = 0;
queue = (int[]) (new int[capacity]); //creates an integer array of the default capacity
}
public void enqueue(int in) {
if (noItems() == queue.length) //if array is full double capacity
expandCapacity();
queue[rear] = in; //add the integer to the rear of the array
rear = (rear+1) % queue.length; //sets the rear to the last element in array
count++;
}
@SuppressWarnings("null")
public int dequeue() throws NoSuchElementException {
if (isEmpty()) //if trying to dequeue from empty array throw exception
throw new NoSuchElementException ("Add to the queue");
int result = queue[front];
queue[front] = (Integer) null; //leaves the previous front before dequeue empty
front = (front + 1) % queue.length; //sets new front
count--; //count - 1
return result;
}
public int noItems() {
return count; //returns number of elements in array
}
public boolean isEmpty() {
return (count == 0); //return true if array is empty
}
public int getCapacityLeft() {
return (capacity - count); //return space left in array
}
public void expandCapacity() {
int[] increase = (int[])(new int[queue.length *2]); //doubles array length
for(int scan=0; scan < count; scan++) //"scans" previous array into new array
{
increase[scan] = queue[front];
front = (front + 1) % queue.length; //returns the remainder of the calculation
}
front = 0; //reset front of queue to new front
rear = count; //rear = number of elements in array
queue = increase;
}
}
这是我的代码必须传递的JUnit测试用例
import java.util.*;
import junit.framework.TestCase;
public class CircularArrayQueueTest extends TestCase
{
private void checkSize( int length, MyQueue queue )
{
assertEquals( "Queue has wrong number of elements", length,
queue.noItems() );
if( length == 0 )
assertTrue( "Queue should be empty", queue.isEmpty() );
else
assertTrue( "Queue should not be empty", !queue.isEmpty() );
}
public void testSimple()
{
MyQueue queue = new CircularArrayQueue();
checkSize( 0, queue );
queue.enqueue( 3 );
checkSize( 1, queue );
try
{
assertEquals( "Dequeue returns wrong element", 3, queue.dequeue() );
} catch( NoSuchElementException e )
{
throw e;
}
checkSize( 0, queue );
}
public void testMultiInput()
{
MyQueue queue = new CircularArrayQueue();
for( int i = 0; i < 1000; ++i )
{
int r = ( int )Math.round( Math.random() );
checkSize( 0, queue );
queue.enqueue( r );
checkSize( 1, queue );
assertEquals( "Dequeue returns wrong element", r, queue.dequeue() );
}
}
public void testManyEnqueueDequeue()
{
CircularArrayQueue queue = new CircularArrayQueue();
int cnt = 0;
for( int i = 0; i < 100000; ++i )
{
if( Math.random() > 0.5 )
{
queue.enqueue( i );
cnt++;
} else
{
if( !queue.isEmpty() )
{
queue.dequeue();
cnt--;
}
}
assertEquals( "Correct number of items", cnt, queue.noItems() );
}
}
public void testLargeQueue()
{
MyQueue queue = new CircularArrayQueue();
int[] r = new int[ 1000 ];
for( int i = 0; i < r.length; ++i )
{
r[ i ] = ( int )Math.round( Math.random() );
checkSize( i, queue );
queue.enqueue( r[ i ] );
}
for( int i = 0; i < r.length; ++i )
{
assertEquals( "Dequeue returns wrong element", r[ i ],
queue.dequeue() );
checkSize( r.length - i - 1, queue );
}
for( int i = 0; i < r.length; ++i )
{
r[ i ] = ( int )Math.round( Math.random() );
checkSize( i, queue );
queue.enqueue( r[ i ] );
}
for( int i = 0; i < r.length; ++i )
{
assertEquals( "Dequeue returns wrong element", r[ i ],
queue.dequeue() );
checkSize( r.length - i - 1, queue );
}
}
public void testThrows()
{
MyQueue queue = new CircularArrayQueue();
int[] r = new int[ 1000 ];
for( int i = 0; i < r.length; ++i )
{
r[ i ] = ( int )Math.round( Math.random() );
checkSize( i, queue );
queue.enqueue( r[ i ] );
}
for( int i = 0; i < r.length; ++i )
{
assertEquals( "Dequeue returns wrong element", r[ i ],
queue.dequeue() );
checkSize( r.length - i - 1, queue );
}
boolean throwsCorrectly = false;
try
{
queue.dequeue();
} catch( NoSuchElementException e )
{
throwsCorrectly = true;
}
assertTrue( "Throws when dequeuing empty queue", throwsCorrectly );
}
public void testResize()
{
CircularArrayQueue queue = new CircularArrayQueue();
assertTrue( "Initial capacity too large", queue.getCapacityLeft() <= 1024 );
for( int i = 0; i < 1000; ++i )
{
queue.enqueue( i );
}
int currentCapacity = queue.getCapacityLeft();
while( currentCapacity > 0 )
{
queue.enqueue( 9 );
currentCapacity--;
assertEquals( "Array size should not change", currentCapacity,
queue.getCapacityLeft() );
}
assertTrue( "Should have reached capacity", queue.getCapacityLeft() == 0 );
queue.enqueue( 42 );
assertTrue( "Should have resized array",
currentCapacity < queue.getCapacityLeft() );
currentCapacity = queue.getCapacityLeft();
for( int i = 0; i < 100; ++i )
{
queue.enqueue( i );
currentCapacity--;
assertEquals( "Resizing too often (inefficient)", currentCapacity,
queue.getCapacityLeft() );
}
}
}
我得到的错误是NullPointerException at CircularArrayQueue.dequeue at TestFailure.testManyEnqueueDequeue
。我假设我从尝试将空数组出列但是不知道如何改变我的dequeue
方法以解决此问题时遇到此错误。为什么我的if(isEmpty())
方法中的dequeue
语句无法解决此问题(假设这是问题)?
添加了故障跟踪详细信息
java.lang.NullPointerException
at tutorialTwo.CircularArrayQueue.dequeue(CircularArrayQueue.java:41)
at tutorialTwo.TestFailure.testManyEnqueueDequeue(TestFailure.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:252)
at junit.framework.TestSuite.run(TestSuite.java:247)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:131)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)