Reputation:
I need help to understand how the testing should go through. I should implement the test method in stacktest.java ( have already done that). Then extend Stacktest with LinkedlistTest ( i have already done that). Then add super.setUp() as the first line in LinkedListTest.setUp (I have done that). But the one overriden method is getIntegerStack that I implement in the LinkedListTest, but then i Get a error " 'getIntegerStack()' in 'LinkedListTest' clashes with 'getIntegerStack()' in 'StackTest'; attempting to use incompatible return type " I dont know how to fix it. I have tested but i dont want to import java.util.stack in StackTest.java, because then my top() method does not work. What should I do?
The testing:
TODO: How should i make the getIntegerStack() do work.
stack interface class:
public interface Stack <T> {
void push ( T elem);
T pop();
T top();
int size();
boolean isEmpty();
}
LinkedList class.
import java.util.EmptyStackException;
import java.util.NoSuchElementException;
/**
* A singly linked list.
*/
public class LinkedList<T> implements Stack <T> {
private ListElement<T> first; // First element in list.
private ListElement<T> last; // Last element in list.
private int size; // Number of elements in list.
/**
* A list element.
*/
private static class ListElement<T> {
public T data;
public ListElement<T> next;
public ListElement(T data) {
this.data = data;
this.next = null;
}
}
/**
* Creates an empty list.
*/
public LinkedList() {
this.first = null;
this.last = null;
this.size = 0;
}
/**
* Inserts the given element at the beginning of this list.
*
* @param element An element to insert into the list.
*/
public void addFirst(T element) {
ListElement<T> firstElement = new ListElement<>(element);
if (this.size == 0){
this.first = firstElement;
this.last = firstElement;
}
else{
firstElement.next = this.first;
this.first = firstElement;
}
this.size ++;
}
/**
* Inserts the given element at the end of this list.
*
* @param element An element to insert into the list.
*/
public void addLast(T element) {
ListElement<T> lastElement = new ListElement<>(element);
if(this.size ==0){
this.first = lastElement;
}
else{
this.last.next = lastElement;
}
this.last = lastElement;
this.size ++;
}
/**
* @return The head of the list.
* @throws NoSuchElementException if the list is empty.
*/
public T getFirst() {
if (this.first != null){
return this.first.data;
}
else{
throw new NoSuchElementException();
}
}
/**
* @return The tail of the list.
* @throws NoSuchElementException if the list is empty.
*/
public T getLast() {
if(this.last != null){
return this.last.data;
}
else{
throw new NoSuchElementException();
}
}
/**
* Returns an element from a specified index.
*
* @param index A list index.
* @return The element at the specified index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public T get(int index) {
if(index < 0|| index >= this.size){
throw new IndexOutOfBoundsException();
}
else{
ListElement<T>element = this.first;
for(int i = 0; i < index; i++){
element = element.next;
}
return element.data;
}
}
/**
* Removes the first element from the list.
*
* @return The removed element.
* @throws NoSuchElementException if the list is empty.
*/
public T removeFirst() {
if(this.first != null || this.size != 0){
ListElement<T> list = this.first;
this.first = first.next;
size --;
if(size()==0){
last = null;
}
return list.data;
}
else{
throw new NoSuchElementException();
}
}
/**
* Removes all of the elements from the list.
*/
public void clear() {
this.first = null;
this.last = null;
this.size =0;
}
/**
* Adds the element to the top of the stock.
* @param elem
*/
@Override
public void push(T elem) {
ListElement <T> list = new ListElement<>(elem);
if( first == null){
first = list;
last = first;
} else{
list.next = first;
first = list;
}
size ++;
}
/**
* Removes and returns the top element in stack,
* that is the element that was last added.
* Throws an EmptyStackException if stack is empty.
* @return the top element in the stack.
*/
@Override
public T pop(){
if(isEmpty()){
throw new EmptyStackException();
}else{
ListElement <T> list = first;
first = first.next;
size --;
return list.data;
}
}
/**
* returns the top element in the stack without removing it.
* Throws an EmptyStackException if stack is empty.
* @return the top element.
*/
@Override
public T top() {
if(isEmpty()){
throw new EmptyStackException();
}else{
return first.data;
}
}
/**
* Returns the number of elements in the stock
* @return The number of elements in the stock.
*/
public int size() {
return this.size;
}
/**
* Note that by definition, the list is empty if both first and last
* are null, regardless of what value the size field holds (it should
* be 0, otherwise something is wrong).
*
* @return <code>true</code> if this list contains no elements.
*/
public boolean isEmpty() {
return first == null && last == null;
}
/**
* Creates a string representation of this list. The string
* representation consists of a list of the elements enclosed in
* square brackets ("[]"). Adjacent elements are separated by the
* characters ", " (comma and space). Elements are converted to
* strings by the method toString() inherited from Object.
*
* Examples:
* "[1, 4, 2, 3, 44]"
* "[]"
*
* @return A string representing the list.
*/
public String toString() {
ListElement<T> listOfElements = this.first;
String returnString = "[";
while(listOfElements != null) {
returnString += listOfElements.data;
if(listOfElements.next != null){
returnString += ", ";
}
listOfElements = listOfElements.next;
}
returnString += "]";
return returnString;
}
}
Testclasses:
import org.junit.Test;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.Timeout;
import static org.junit.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import java.lang.Integer;
import java.util.EmptyStackException;
import java.util.stream.IntStream;
/**
* Abstract test class for Stack implementations.
*
* Implementing test classes must only implement the getIntegerStack
* method. Be careful not to override ANY other methods!
*
*/
public abstract class StackTest{
@Rule public Timeout globalTimeout = Timeout.seconds(5);
private Stack<Integer> stack;
private int[] valuesInStack;
private int initialStackSize;
private Stack<Integer> emptyStack;
@Before
public void setUp() {
valuesInStack = new int[] {3, 4, 1, -123, 4, 1};
initialStackSize = valuesInStack.length;
stack = getIntegerStack();
pushArrayToStack(valuesInStack, stack);
emptyStack = getIntegerStack();
}
/**
* Push an array to the stack, in order.
*
* @param array An int array.
* @param stack A Stack.
*/
private void pushArrayToStack(int[] array, Stack<Integer> stack) {
for (int i = 0; i < array.length; i++) {
stack.push(array[i]);
}
}
/**
* This is the only method that implementing classes need to override.
*
* @return An instance of Stack.
*/
protected abstract Stack<Integer> getIntegerStack();
@Test
public void topIsLastPushedValue() {
// Arrange
int value = 1338;
// Act
emptyStack.push(value);
stack.push(value);
int emptyStackTop = emptyStack.top();
int stackTop = stack.top();
// Assert
assertThat(emptyStackTop, equalTo(value));
assertThat(stackTop, equalTo(value));
}
// HELPERS
/**
* Pops the desired amount of elements.
*
* @param stack A Stack.
* @param amountOfElements The amount of elements to pop.
*/
private void popElements(Stack<Integer> stack, int amountOfElements) {
for (int i = 0; i < amountOfElements; i++) {
stack.pop();
}
}
/**
* Class used for stream operations when both actual and expected values
* need to be gather in conjunction.
*/
private class ResultPair<T> {
public final T actual;
public final T expected;
public ResultPair(T actual, T expected) {
this.actual = actual;
this.expected = expected;
}
}
}
import org.junit.Test;
import org.junit.Before;
import static org.junit.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Stack;
/**
* Test class for LinkedList
*
* The following invariants are checked for several different states and for
* each of the methods that mutate the list.
*/
public class LinkedListTest extends StackTest{
/* A sequence of integers */
private int[] elements;
/* An empty linked list */
private LinkedList<Integer> list;
@Before
public void setUp() {
super.setUp();
list = new LinkedList<Integer>();
elements = new int[]{-919, 388, 67, -248, -309, -725, 904, 53,
90, -469, -559, 256, 612, 366, -412, -221,
347, -921, -978, 324, -858, 480, -443, 891,
329, -5, 878, -538, 445, -366, 760, 52};
}
/**
* This is the only method that implementing classes need to override.
*
* @return An instance of Stack.
*/
@Override
protected Stack<Integer> getIntegerStack() {
return null;
}
}
Upvotes: 0
Views: 109
Reputation: 6985
In StackTest
your abstract method protected abstract Stack<Integer> getIntegerStack();
should return the Stack
interface you created. At least that's what it looks like due to no imports of classes named Stack. But in LinkedListTest
the method implementation returns java.util.Stack
. Note this:
import java.util.Stack;
It's the last import in LinkedListTest.
The declared method is expecting implementors to return your.package.Stack
, but you are returning java.util.Stack
, and those need to match, no way around that. So remove the aforementioned import, there will be no more compilation errors, and you can start testing.
Edit:
If your Stack
interface does not reside in any additional packages, you should just remove the import. If you have declared it in some package of your own, you should change the import to
import your.package.Stack;
where your.package.
is whatever package you declared the interface in.
About the implementation of the abstract method, you should return a new instance of Stack
, as written in the comments. That means returning new instance of your LinkedList
implementation.
Upvotes: 1