I'm trying to implement a Queue but my method "enqueue(E e)" is giving me an error saying that the method clashes with the method in the Queue interface but neither override the other. What is going on?
Here is the Queue Interface
public interface Queue<E> {
/**
* Returns the number of elements in the queue.
*/
int size();
/**
* Tests whether the queue is empty.
*/
boolean isEmpty();
/**
* Inserts an element at the rear of the queue.
*/
void enqueue(E e);
/**
* Returns, but does not remove, the first element of the queue (null if empty).
*/
E first();
/**
* Removes and returns the first element of the queue (null if empty).
*/
E dequeue();
}
And here is the implementation
/**
* Implementation of the queue ADT using a fixed-length array.
* #param <E>
*/
public class ArrayQueue<E> implements Queue {
// instance variables
private E[] data;
private int f = 0;
private int sz = 0;
public static final int CAPACITY = 1000;
// Constructors
public ArrayQueue() {
this(CAPACITY);
}
public ArrayQueue(int capacity) {
data = (E[]) new Object[capacity];
}
// methods
/**
* Returns the number of elements in the queue
*/
public int size() {
return sz;
}
/**
* Tests whether the queue is empty.
*/
public boolean isEmpty() {
return sz == 0;
}
/**
* Inserts an element at the rear of the queue.
*/
public void enqueue(E e) throws IllegalStateException {
if (sz == data.length)
throw new IllegalStateException("Queue is full");
int avail = (f + sz) % data.length;
data[avail] = e;
sz++;
}
/**
* Returns, but does not remove, the first element of the queue (null if empty)
*/
public E first() {
if (isEmpty())
return null;
return data[f];
}
/**
* Removes and returns the first element of the queue (null if empty)
*/
public E dequeue() {
if (isEmpty())
return null;
E answer = data[f];
data[f] = null;
f = (f + 1) % data.length;
sz--;
return answer;
}
}
I've tried removing the "throws new IllegalStateError" and copy and pasting to make sure the spelling was the same. I can't figure out what the problem is. Both of these code fragments come straight out of a book...
Related
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:
StackTest.java is an abstract test class.
For each implementation of Stack, one may simply extend StackTest with an implementing test class. The only method that should be overridden is StackTest.getIntegerStack, which should simply return an instance of a class that implements Stack. See the setUp method in StackTest and try to understand how this works.
In your case, you should extend StackTest with a test class called LinkedListTest.
you must add a call to super.setUp(); as the first line in LinkedListTest.setUp.
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;
}
}
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.
Completely stuck on this error. Here's the class the error is coming from.
/** An array-based Stack. */
public class ArrayStack<E> implements Stack {
/** Array of items in this Stack. */
private E[] data;
/** Number of items currently in this Stack. */
private int size;
/** The Stack is initially empty. */
public ArrayStack() {
data = (E[])(new Object[1]); // This causes a compiler warning
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public Object pop() {
if (isEmpty()) {
throw new EmptyStructureException();
}
size--;
return data[size];
}
public Object peek() {
if (isEmpty()) {
throw new EmptyStructureException();
}
return data[size - 1];
}
/** Return true if data is full. */
protected boolean isFull() {
return size == data.length;
}
public void push(Object target) {
if (isFull()) {
stretch();
}
data[size] = target;
size++;
}
/** Double the length of data. */
protected void stretch() {
E[] newData = (E[])(new Object[data.length * 2]); // Warning
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
data = newData;
}
}
Here's the Stack class just in case it's needed:
/** A last-in, first-out stack. */
public interface Stack<E> {
/** Return true if this Stack is empty. */
public boolean isEmpty();
/**
* Return the top item on this Stack, but do not modify the Stack.
* #throws EmptyStructureException if this Stack is empty.
*/
public E peek();
/**
* Remove and return the top item on this Stack.
* #throws EmptyStructureException if this Stack is empty.
*/
public E pop();
/** Add target to the top of the Stack. */
public void push(E target);
}
The error is in regards to the line data[size] = target; in the ArrayStack class, in the push(Object target) method.
data[size] = target;
1) Here data refers to E array and target refers to Object.
Generics brings type safety. So you cannot cannot convert from Object to E.
2) public class ArrayStack<E> implements Stack {
is not correct because you don't provide the parameterized type for the interface you are implementing.
Writing public class ArrayStack<E> implements Stack<E> { would be safer and will force you to implement the Stack methods by respecting the parameterized type used in the Stack methods.
For example : public void push(E target);
3) To be conform to declared parameterized type in ArrayStack you should should use the parameterized type in your method instead of Object.
so you should replace
public void push(Object target) {
by
public void push(E target) {
And you should do the same thing in all methods you declare that manipulate as declared type Object instead of E. For example :
public Object peek()
and
public Object pop() {
Since your data array is of type E:
private E[] data;
You need to modify:
public void push(Object target) {
to have parameter type E.
E can be String, Integer etc determined at runtime. Object is not equivalent to the runtime type.
Target and data are not of the same type. You can use E wherhever you need a type. This makes your code more type safe.
Change the push method to:
public void push(E target) {
if (isFull()) {
stretch();
}
data[size] = target;
size++;
}
Try this:
/**
* An array-based Stack.
*/
public class ArrayStack<E> implements Stack<E> {
/**
* Array of items in this Stack.
*/
private E[] data;
/**
* Number of items currently in this Stack.
*/
private int size;
/**
* The Stack is initially empty.
*/
public ArrayStack() {
data = (E[]) (new Object[1]); // This causes a compiler warning
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public E pop() {
if (isEmpty()) {
throw new RuntimeException();
}
size--;
return data[size];
}
public E peek() {
if (isEmpty()) {
throw new RuntimeException();
}
return data[size - 1];
}
/**
* Return true if data is full.
*/
protected boolean isFull() {
return size == data.length;
}
public void push(E target) {
if (isFull()) {
stretch();
}
data[size] = target;
size++;
}
/**
* Double the length of data.
*/
protected void stretch() {
E[] newData = (E[]) (new Object[data.length * 2]); // Warning
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
data = newData;
}
}
I'm doing some school exercises about implementing interfaces and I've already got the workspace and Test classes provided for me. What I have to do is basically implement the methods, run the Test Classes, and make sure they pass the tests.
Here is my code: http://pastebin.com/e8Vh3snC
package queue;
import java.util.*;
public class FifoQueue<E> extends AbstractQueue<E> implements Queue<E> {
private QueueNode<E> last;
private int size=0;
private FifoQueue<E> queue;
public FifoQueue() {
queue = new FifoQueue<E>();
}
/**
* Returns an iterator over the elements in this queue
* #return an iterator over the elements in this queue
*/
public Iterator<E> iterator() {
return queue.iterator();
}
/**
* Returns the number of elements in this queue
* #return the number of elements in this queue
*/
public int size() {
return size;
}
/**
* Inserts the specified element into this queue, if possible
* post: The specified element is added to the rear of this queue
* #param x the element to insert
* #return true if it was possible to add the element
* to this queue, else false
*/
public boolean offer(E x) {
if(queue.add(x)){
size++;
return true;
} else {
return false;
}
}
/**
* Retrieves and removes the head of this queue,
* or null if this queue is empty.
* post: the head of the queue is removed if it was not empty
* #return the head of this queue, or null if the queue is empty
*/
public E poll() {
if(queue.size() > 0) {
size=size-1;
}
return queue.poll();
}
/**
* Retrieves, but does not remove, the head of this queue,
* returning null if this queue is empty
* #return the head element of this queue, or null
* if this queue is empty
*/
public E peek() {
return queue.peek();
}
private static class QueueNode<E> {
E element;
QueueNode<E> next;
private QueueNode(E x) {
element = x;
next = null;
}
}
}
Here are the Test Classes, in case you want to see them (provided by the school, so I doubt they're incorrect): http://pastebin.com/uV46j0rm
package testqueue;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.NoSuchElementException;
import java.util.Iterator;
import queue.FifoQueue;
public class TestFifoQueue {
private FifoQueue<Integer> myIntQueue;
private FifoQueue<String> myStringQueue;
#Before
public void setUp() throws Exception {
myIntQueue = new FifoQueue<Integer>();
myStringQueue = new FifoQueue<String>();
}
#After
public void tearDown() throws Exception {
myIntQueue = null;
myStringQueue = null;
}
/**
* Test if a newly created queue is empty.
*/
#Test
public final void testNewFifoQueue() {
assertTrue(myIntQueue.isEmpty());
assertTrue(myIntQueue.size() == 0);
}
/** Test a single offer followed by a single peek. */
#Test
public final void testPeek() {
myIntQueue.offer(1);
int i = myIntQueue.peek();
assertEquals("peek on queue of size 1", 1, i);
assertTrue(myIntQueue.size() == 1);
}
/**
* Test a single offer followed by a single poll.
*/
#Test
public final void testPoll() {
myIntQueue.offer(1);
int i = myIntQueue.poll();
assertEquals("poll on queue of size 1", 1, i);
assertTrue("Wrong size after poll", myIntQueue.size() == 0);
}
/**
* Test peek of empty queue.
*/
#Test
public final void testPeekOfEmpty() {
assertEquals("Front of empty queue not null", null, myIntQueue.peek());
}
/**
* Test poll of empty queue.
*/
#Test
public final void testPollOfEmpty() {
assertEquals("Poll of empty queue should return null", null, myIntQueue
.poll());
}
/**
* Test that implementation works for a queue of strings.
*/
#Test
public final void testStringQueue() {
myStringQueue.offer("First");
myStringQueue.offer("Second");
myStringQueue.offer("Third");
assertTrue("Wrong size of queue", myStringQueue.size() == 3);
assertEquals("peek on queue of strings", "First", myStringQueue.peek());
assertEquals("String First expected", "First", myStringQueue.poll());
assertEquals("String Second expected", "Second", myStringQueue.poll());
assertEquals("String Third expected", "Third", myStringQueue.poll());
assertTrue("Queue of strings should be empty", myStringQueue.isEmpty());
}
/**
* Test that polling gives elements in right order.
*/
#Test
public final void testOrder() {
myIntQueue.offer(1);
myIntQueue.offer(2);
myIntQueue.offer(3);
myIntQueue.offer(4);
myIntQueue.offer(5);
for (int i = 1; i <= 5; i++) {
int k = myIntQueue.poll();
assertEquals("poll returns incorrect element", i, k);
}
assertTrue("Queue not empty", myIntQueue.isEmpty());
}
/**
* Test that polling all elements gives an empty queue.
*/
#Test
public final void testMakeQueueEmpty() {
myIntQueue.offer(1);
myIntQueue.offer(2);
myIntQueue.poll();
myIntQueue.poll();
assertTrue("Wrong size after poll", myIntQueue.size() == 0);
assertTrue("Queue not empty after poll", myIntQueue.isEmpty());
myIntQueue.offer(3);
myIntQueue.offer(4);
assertTrue("Wrong size after offer", myIntQueue.size() == 2);
for (int i = 3; i <= 4; i++) {
int k = myIntQueue.poll();
assertEquals("poll returns incorrect element", i, k);
}
assertTrue("Wrong size after poll", myIntQueue.size() == 0);
assertTrue("Queue not empty after poll", myIntQueue.isEmpty());
}
}
So when I try to run the tests, I get multiple StackOverflowErrors at queue.FifiQueue.(FifoQueue.java:10)
I've been looking through the code for some hours now but can't figure out where I've written bad code.
PS: I know some of the methods are implemented incorrectly (I will try to fix them later) but as for now I'm just trying to pass the offer() och size() methods.
Your constructor is calling itself, causing infinite recursion:
public FifoQueue() {
queue = new FifoQueue<E>();
}
Maybe you mean to wrap some other type of queue or list internally?
I have a task to code the below class ... I have a problem in iterator() method
I have many errors in it , I do not know how to do to correct it .. Can you suggest a way to correct the code under iterator() method ... You can as well see the other parts of the class ...I put the comments from eclipse next to each infected line.. thanks
package queue;
import java.util.*;
public class FifoQueue<E> extends AbstractQueue<E> implements Queue<E> {
private QueueNode<E> last;
private int size;
public FifoQueue() {
}
/**
* Returns an iterator over the elements in this queue
* #return an iterator over the elements in this queue
*/
public Iterator<E> iterator() {
QueueNode<E> position =last;
Iterator itr = position.iterator(); // The method iterator() is //undefined for the type FifoQueue.QueueNode<E>- Iterator is a raw type. References //to generic type Iterator<E> should be
parameterized
while(itr.hasNext){ // hasNext cannot be resolved or is not a field
int object=itr.next(); //Type mismatch: cannot convert from Object to int
return object; //Type mismatch: cannot convert from int to Iterator<E>
}
}
/**
* Returns the number of elements in this queue
* #return the number of elements in this queue
*/
public int size() {
return size;
}
/**
* Inserts the specified element into this queue, if possible
* post: The specified element is added to the rear of this queue
* #param x the element to insert
* #return true if it was possible to add the element
* to this queue, else false
*/
public boolean offer(E x) {
QueueNode<E> q = new QueueNode<E>(x);
if(last!=null){
q.next=last.next;
last.next=q;
return true;
} else {
return true;
}
}
/**
* Retrieves and removes the head of this queue,
* or null if this queue is empty.
* post: the head of the queue is removed if it was not empty
* #return the head of this queue, or null if the queue is empty
*/
public E poll() {
if( last==null){
return null;
}
QueueNode<E> n=last.next;
last.next=last.next.next;
size=size-1;
return n.element;
}
/**
* Retrieves, but does not remove, the head of this queue,
* returning null if this queue is empty
* #return the head element of this queue, or null
* if this queue is empty
*/
public E peek() {
if(last==null){
return null;
}
QueueNode<E> n=last;
while(n.next !=null){
}
return n.element;
}
private static class QueueNode<E> {
E element;
QueueNode<E> next;
private QueueNode(E x) {
element = x;
next = null;
}
}
}
Your iterator() method needs to return an implementation of the Iterator<E> interface. You'd likely want to do this as a private inner class, so it has access to the queue fields.
The iterator class needs to keep the current position, and step through your nodes on calls to next().
You might want to implement fail-fast logic to prevent issues with updating the queue while iterating. Add a change counter to the queue, and increment on change (insert/remove). Remember the change counter at the time the iterator is created, and if different on a call to next(), throw ConcurrentModificationException.
This is a skeleton to get you started:
public Iterator<E> iterator() {
return new FifoIterator();
}
private final class FifoIterator implements Iterator<E> {
private QueueNode<E> curr;
FifoIterator() {
this.curr = FifoQueue.this.last;
}
#Override
public boolean hasNext() {
return (this.curr != null);
}
#Override
public E next() {
if (this.curr == null)
throw new NoSuchElementException();
this.curr = this.curr.next;
E e = this.curr.element;
if (this.curr == FifoQueue.this.last)
this.curr = null;
return e;
}
}
I've this custom class named MyAbstractList which implements MyList interface. Here's the code:
public abstract class MyAbstractList<E> implements MyList<E> {
protected int size = 0; // The size of the list
protected MyAbstractList() {
}
protected MyAbstractList(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
public void add(E e) {
add(size, e);
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public boolean addAll(MyList<E> otherList) {
for (E e : otherList) {
add(e);
}
if (otherList.size() > 0)
return true;
return false;
}
public boolean removeAll(MyList<E> otherList) {
boolean removed = false;
for (E e : otherList) {
if (remove(e) && !removed)
removed = true;
}
return removed;
}
public boolean remove(E e) {
if (indexOf(e) >= 0) {
remove(indexOf(e));
return true;
} else
return false;
}
/** Retains the elements in this list that are also in otherList
* Returns true if this list changed as a result of the call */
public boolean retainAll(MyList<E> otherList) {
}
}
How to implement the retainAll() method?
MyList interface:
public interface MyList<E> extends java.lang.Iterable<E> {
/** Add a new element at the end of this list */
public void add(E e);
/** Add a new element at the specified index in this list */
public void add(int index, E e);
/** Clear the list */
public void clear();
/** Return true if this list contains the element */
public boolean contains(E e);
/** Return the element from this list at the specified index */
public E get(int index);
/** Return the index of the first matching element in this list.
* Return -1 if no match. */
public int indexOf(E e);
/** Return true if this list contains no elements */
public boolean isEmpty();
/** Return the index of the last matching element in this list
* Return -1 if no match. */
public int lastIndexOf(E e);
/** Remove the first occurrence of the element o from this list.
* Shift any subsequent elements to the left.
* Return true if the element is removed. */
public boolean remove(E e);
/** Remove the element at the specified position in this list
* Shift any subsequent elements to the left.
* Return the element that was removed from the list. */
public E remove(int index);
/** Replace the element at the specified position in this list
* with the specified element and returns the new set. */
public Object set(int index, E e);
/** Return the number of elements in this list */
public int size();
/** Adds the elements in otherList to this list.
* Returns true if this list changed as a result of the call */
public boolean addAll(MyList<E> otherList);
/** Removes all the elements in otherList from this list
* Returns true if this list changed as a result of the call */
public boolean removeAll(MyList<E> otherList);
/** Retains the elements in this list that are also in otherList
* Returns true if this list changed as a result of the call */
public boolean retainAll(MyList<E> otherList);
/** Return an iterator for the list */
public java.util.Iterator<E> iterator();
}
If elements are not Comparable you can only search for elements of your list not present in the parameter.
public boolean retainAll(MyList<E> otherList) {
boolean changed = false;
for (int i = size() - 1; i >= 0; i--) {
Object obj = get(i);
if (!otherList.contains(obj)) {
remove(i);
changed = true;
}
}
return changed;
}
Note: this algorithm is done in O(n^2), if you have list of Comparable you can go to O(n log(n))
Second note: don't use an iterator to loop the list because a change on the content of the list may throw an Exception.
Comment on suggested edit by Saud: It is not necessary to update the size. This must be done by the method remove.