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;
}
}
Related
I am trying to develop my knowledge of the Queue interface by implementing it in my own "MyQueue" class. However, I want to override the iterator() method. Since I can't implement both the Iterator and Queue interfaces at the same time, I am at a loss.
On my iterator() method Eclipse is giving me the error, cannot convert from MyQueue<E>.QueueIterator to Iterator<E> when I mouse over the red underline below the words new QueueIterator().
Also, when I try to implement my "QueueIterator" inner class, Eclipse gives me the error, syntax error on token "class", # expected when I mouse over the red underline below the word class.
In the code examples below, I have removed all methods that have nothing to do with my question. I know I have to implement these methods to implement Queue. I'm just trying to make the problem clearer.
How can I override the iterator() method?
MyQueue class:
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Queue;
/**
* A custom queue class. Uses a singly-linked list.
*/
public class MyQueue<E> implements Queue {
// the top of the queue
private Node<E> first;
private int size;
/**
* Creates new myQueue object
*/
public MyQueue() {
first = null;
current = null;
size = 0;
}
#Override
public Iterator<E> iterator() {
return new QueueIterator();
}
/**
* Holds Objects and points to the next one.
*
*/
private class Node<E> {
private E data;
private Node<E> next;
/**
* Creates a Node object
* #param data The Object to be held by the Node
*/
Node(E data) {
this.data = data;
this.next = null;
}
private Node<E> getNext() {
return this.next;
}
private E getData() {
return this.data;
}
}
/**
* Iterator implementation
*/
private class QueueIterator() {
private Node<E> curNode;
public QueueIterator() {
curNode = null;
}
public boolean hasNext() {
if(curNode == null && first != null) {
return true;
} else if (curNode.getNext() != null) {
return true;
} else {
return false;
}
}
public E next() {
if(curNode == null && first != null) {
curNode = first;
return curNode.getData();
}
if(!hasNext()) {
throw new NoSuchElementException();
}
curNode = curNode.getNext();
return curNode.getData();
}
}
QueueIterator needs to implement Iterator<E>.
You shouldn't have the parentheses on this line:
private class QueueIterator() {
It should be just:
private class QueueIterator {
Actually:
private class QueueIterator implements Iterator<E> {
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...
I'm working on coding some data structures on my own time. I've noticed that the clone method is not copying the list as I expect. I'll post my results underneath the code as the main method is near the bottom of the class. Here is the class I have written so far:
public class DoublyLinkedList<E> implements Cloneable {
//------------nested Node class------------
private static class Node<E> {
private E element; // reference to stored element
private Node<E> prev; // reference to previous element
private Node<E> next; // reference to next element
/** The constructor that creates a node */
public Node(E e, Node<E> p, Node<E> n) {
element = e;
prev = p;
next = n;
}
// methods
/** getter for the element */
public E getElement() {
return element;
}
/** getter for previous node in list */
public Node<E> getPrev() {
return prev;
}
/** getter for next node in list */
public Node<E> getNext() {
return next;
}
/** setter for previous node */
public void setPrev(Node<E> p) {
prev = p;
}
/** setter for the next node */
public void setNext(Node<E> n) {
next = n;
}
} //------------end of nested node class------------
// instance variables of DoublyLinkedList
private Node<E> header; // head sentinel
private Node<E> trailer; // tail sentinel
private int size = 0; // number of elements in list
/** List constructor */
public DoublyLinkedList() {
header = new Node<E>(null, null, null); // create header
trailer = new Node<E>(null, header, null); // header precedes trailer
header.setNext(trailer); // trailer follows header
}
// access methods
/** Returns the size of the doubly linked list */
public int getSize() {
return size;
}
/** Tests whether the linked list is empty */
public boolean isEmpty() {
return size == 0;
}
/** Returns but does not remove the first element in the list */
public E first() {
if (isEmpty()) {
return null;
} else {
return header.getNext().getElement(); // return first node's element
}
}
/** Returns but does not remove the last element in the list */
public E last() {
if (isEmpty()) {
return null;
} else {
return trailer.getPrev().getElement(); // return last node's element
}
}
//update methods
/** Adds element e to the front of the list */
public void addFirst(E e) {
addBetween(e, header, header.getNext());
}
/** Adds element e to the back of the list */
public void addLast(E e) {
addBetween(e, trailer.getPrev(), trailer);
}
/** Removes and returns the first element of the list */
public E removeFirst() {
if (isEmpty()) {
return null;
} else {
return remove(header.getNext());
}
}
/** Removes and returns the last element of the list */
public E removeLast() {
if (isEmpty()) {
return null;
} else {
return remove(trailer.getPrev());
}
}
// private update helpers
/** Does the heavy lifting for adding an element to the list */
private void addBetween(E e, Node<E> predecessor, Node<E> successor) {
// create and link a new node
Node<E> newest = new Node<>(e, predecessor, successor);
predecessor.setNext(newest);
successor.setPrev(newest);
size++;
}
/** Does the heavy lifting for removing an element from the list */
private E remove(Node<E> node) {
Node<E> predecessor = node.getPrev();
Node<E> successor = node.getNext();
predecessor.setNext(successor);
successor.setPrev(predecessor);
size--;
return node.getElement();
}
// equals and clone methods
/** Equals method currently assumes that the list must be of the same
* type in order to be equal. This means that a doubly linked list will
* not be equal to a circularly linked list or a singly linked list even
* if the elements are identical. Because of type erasure in Java, we have
* to use Objects and casts to handle any type rather than generics. */
#SuppressWarnings({ "rawtypes" })
public boolean equals(Object o) {
if (o == null) {
return false;
}
// at this point, the classes have to be the same.
if (getClass() != o.getClass()) {
return false;
}
DoublyLinkedList other = (DoublyLinkedList) o; // use non-parameterized type (erasure)
// the size must be the same for them to be equal
if (size != other.size) {
return false;
}
Node walkA = header; // traverse primary list
Node walkB = other.header; // traverse secondary list
// We don't want to compare the trailers, so size - 1
for(int i = 0; i < size; i++) {
if (!walkA.getElement().equals(walkB.getElement())) {
return false; // mismatch
}
walkA = walkA.getNext();
walkB = walkB.getNext();
}
return true; // if we reach this, then they are equal.
}
/** The clone method that performs a deep clone of the list */
#SuppressWarnings("unchecked")
public DoublyLinkedList<E> clone() throws CloneNotSupportedException {
// always use inherited Object.clone() to create initial copy
DoublyLinkedList<E> other = (DoublyLinkedList<E>) super.clone(); // safe cast
if (size > 0) { // we need independent node chain
other.header = new Node<>(null, null, null);
other.trailer = new Node<>(null, other.header, null);
other.header.setNext(other.trailer);
Node<E> walk = header.getNext(); // walk through remainder of original list
Node<E> otherWalk = other.header;
for(int i = 0; i < size; i++) { // make new node storing same element
Node<E> newest = new Node<>(walk.getElement(), null, null);
otherWalk.setNext(newest); // link previous node to this one
otherWalk = newest;
otherWalk.setPrev(newest); // link node back to the previous one
walk = walk.getNext();
}
}
return other;
}
/** Test driver for the circularly linked list class */
#SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String args[]) {
DoublyLinkedList theList = new DoublyLinkedList();
DoublyLinkedList clonedList;
theList.addFirst(1);
theList.addFirst(2);
theList.addLast(3);
try {
clonedList = theList.clone();
System.out.println("Original List values");
while(theList.first() != null) {
System.out.println(theList.removeFirst());
}
System.out.println("Cloned List values");
while(clonedList.first() != null) {
System.out.println(clonedList.removeFirst());
}
System.out.println(theList.equals(clonedList));
} catch (CloneNotSupportedException e) {
System.err.println("I AM ERROR: List didn't clone.");
e.printStackTrace();
}
}
} //------------ end of doubly linked list class ------------
The main method in this class is just for testing. It should be pretty straightforward. However, whenever I run this code, I get the following result:
Original List values
2
1
3
Cloned List values
2
2
2
true
I'm not sure why the Cloned List values are not the same as those in the original list. I tried changing the 2 in the code to a 4 to see if I would get three 4s out of my cloned list, and indeed I did. Perhaps the list is not walking and grabs the element at the front of the list n times.
Do any of you see my mistake?
What about using the already existing API to create a correct DoubleLinkedList?
public DoublyLinkedList<E> clone() throws CloneNotSupportedException {
// always use inherited Object.clone() to create initial copy
DoublyLinkedList<E> other = new DoublyLinkedList<>();
if (size > 0) {
Node<E> walk = header.getNext();
for(int i = 0; i < size; i++) {
other.addLast(walk.getElement());
walk = walk.getNext();
}
}
return other;
}
That way you don't have to worry about your entire list logic in multiple places.
Alternatively keeping your current approach you can do the following
public DoublyLinkedList<E> clone() throws CloneNotSupportedException {
// always use inherited Object.clone() to create initial copy
DoublyLinkedList<E> other = (DoublyLinkedList<E>) super.clone();
if (size > 0) {
other.header = new Node<>(null, null, null);
other.trailer = new Node<>(null, other.header, null);
other.header.setNext(other.trailer);
Node<E> walk = header.getNext();
Node<E> otherWalk = other.header;
for(int i = 0; i < size; i++) {
Node<E> newest = new Node<>(walk.getElement(), otherWalk, otherWalk.getNext());
otherWalk.getNext().setPrev(newest);
otherWalk.setNext(newest);
otherWalk = otherWalk.getNext();
walk = walk.getNext();
}
}
return other;
}
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.
It's just not working ):
Here's my toString() method.
public String toString() {
String s= "[";
DoublyLinkedList<E>.ListNode next= new ListNode(null,null,null);
next= head.successor();
while(next!=tail){
s+= next.getValue()+ ", ";
next=next.successor();
}
s +="]";
// Write this method body and remove this comment
return s;
}
it tells me there's a null pointer error at "next= head.successor()"
Here's the class ListNode:
/** An instance is a node of this list. */
public class ListNode {
/** Predecessor of this node on the list (null if the list is empty). */
private ListNode pred;
/** The value of this node. */
private E value;
/** Successor of this node on the list. (null if the list is empty). */
private ListNode succ;
/** Constructor: an instance with predecessor p (p can be null),
* successor s (s can be null), and value v. */
private ListNode(ListNode p, ListNode s, E v) {
pred= p;
succ= s;
value= v;
}
/** Return the value of this node. */
public E getValue() {
return value;
}
/** Return the predecessor of this node in the list (null if this node
* is the first node of this list). */
public ListNode predecessor() {
return pred;
}
/** Return the successor of this node in the list (null if this node
* is the last node of this list). */
public ListNode successor() {
return succ;
}
And DoublyLinkedList...
/** An instance is a doubly linked list. */
public class DoublyLinkedList<E> {
private ListNode head; // first node of linked list (null if none)
private ListNode tail; // last node of linked list (null if none)
private int size; // Number of values in linked list.
/** Constructor: an empty linked list. */
public DoublyLinkedList() {
}
/** Return the number of values in this list. */
public int size() {
return size;
}
/** Return the first node of the list (null if the list is empty). */
public ListNode getHead() {
return head;
}
/** Return the last node of the list (null if the list is empty). */
public ListNode getTail() {
return tail;
}
/** Return the value of node e of this list.
* Precondition: e must be a node of this list; it may not be null. */
public E valueOf(ListNode e) {
return e.value;
}
You should implement Iterable for your list.
public class DoublyLinkedList<E> implements Iterable<E> {
...
public Iterator<E> iterator() {
// TODO: return a new iterator here.
}
}
Then implement an Iterator<E> for your list as an inner class. See Java source code for examples:
java.util.AbstractList
java.util.LinkedList ListItr
It is a well-established pattern for iterating through lists. Then, you don't have to worry about getting your while loop right, instead, you can just use standard for each loops:
for (E item: this) {
}