I created an interface called LLIterator that extends iterator and add two methods to it, when i tried to use it in one of my class, I couldn't compile it. Here is what I got.
my custom interface is like this:
import java.util.Iterator;
public interface LLIterator<T> extends Iterator<T>{
boolean hasNext();
T next();
void remove();
void addBefore(T element);
void addAfter(T element);
}
my linkedlist is like this:
import java.lang.StringBuilder;
import java.util.NoSuchElementException;
import java.util.Iterator;
import java.util.ArrayList;
/**
* A class to represent a linked list of nodes.
*/
public class LinkedList<T> implements Iterable<T>{
/** the first node of the list, or null if the list is empty */
private LLNode<T> first;
/** some codes here
#Override
public LLIterator<T> iterator() {
return new LinkedListIterator();
}
private class LinkedListIterator implements LLIterator<T>{
LLNode<T> nodeptr = first;
final LinkedList<T> list = getList();
#Override
public void addBefore(T element){
if(nodeptr == first || list.isEmpty()){
throw new NoSuchElementException();
}
LLNode<T> newnode = new LLNode<T>(element, null);
newnode.setNext(nodeptr);
}
#Override
public void addAfter(T element){
LLNode<T> newnode;
if(nodeptr == first || list.isEmpty()){
newnode = new LLNode<T>(element, null);
list.setFirst(newnode);
}
newnode = new LLNode<T>(element, null);
newnode.setNext(nodeptr.getNext());
nodeptr.setNext(newnode);
}
}
in another class, i used iterator method of the this Linkedlist and called addBefore method, however when I compile it, it shows
cannot find symbol
symbol: method addAfter(WordData)
location: variable iterator of type java.util.Iterator<WordData>
here is part of my another class:
public void addFollowingWord(String word){
Iterator<WordData> iterator = list.iterator();
WordData current = iterator.next();
while(iterator.hasNext()){
if(current.getWord().equals(word)){
current.incrementCount();
}
else if(current.getWord().compareTo(word) < 0){
current = iterator.next();
}
else if(current.getWord().compareTo(word) > 0){
WordData newword = new WordData(word);
iterator.addBefore(newword);
}
}
if(!iterator.hasNext()){
WordData newword = new WordData(word);
iterator.addAfter(newword);
}
}
I'm very confused, did I make any mistake somewhere or I missed something?
You can't access the methods on the custom interface because it's cast as Iterator. Update your iterator() method to return your subinterface:
#Override
public LLIterator<T> iterator() {
return new LinkedListIterator();
}
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 creating a LinkedList class and a LinkedListNode and I want them to be generic so that I can choose type arguments later depending on the situation.
So I created these two classes:
DoublyLinkedList class:
public class DoublyLinkedList<T> {
// sentinel before first item
private NodeDoublyLinked<T> head;
// sentinel after last item
private NodeDoublyLinked<T> tail;
//number of elements
private int size;
// getter and setter methods here
//add new node to the linked List
public void addNode(T data){
NodeDoublyLinked<T> prev = tail.getPrev();
NodeDoublyLinked<T> node = new NodeDoublyLinked(data, prev, tail);
tail.setPrev(node);
size++;
}
}
and the NodeDoublyLinked class:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class NodeDoublyLinked<T> implements Iterable<T> {
private T data;
private NodeDoublyLinked<T> prev;
private NodeDoublyLinked<T> next;
public NodeDoublyLinked(T value, NodeDoublyLinked<T> previousN, NodeDoublyLinked<T> nextN) {
this.data = value;
this.prev = previousN;
this.next = nextN;
}
// getter and setter methods
#Override
public Iterator<T> iterator() {
return new NodeDoublyLinkedIterator();
}
private class NodeDoublyLinkedIterator implements Iterator<T> {
// the current node returned by next()
NodeDoublyLinked<T> current = prev.next;
#Override
public boolean hasNext() {
return current != null;
}
#Override
public T next() {
// code here
}
public void remove(){
// code here
}
}
}
In the method addNode in DoublyLinkedList class, at this line:
NodeDoublyLinked<T> node = new NodeDoublyLinked(data, prev, tail);
I get a warning:
NodeDoublyLinked is a raw type. References to generic type
NodeDoublyLinked should be parameterized
I checked the documentation of generics and type inference so I understand that I should assign a type parameter at the right side but it's not correct either. Should I replace the type parameter with a type argument like Integer for example? Is there something wrong with the constructor of NodeDoublyLinked?
I'm trying to debug a part of a program that peeks at a queue object from a queue class I implemented myself, so I'm trying to iterate over it and print out all the elements to see what's wrong without altering the queue. How can I do this?
My Queue class (QueueLinkedList is the name):
public class QueueLinkedList<Customer> implements Queue<Customer> {
Node first, last;
public class Node {
Customer ele;
Node next;
}
public QueueLinkedList() {}
public boolean isEmpty() {
return first == null;
}
public QueueLinkedList<Customer> enqueue(Customer ele) {
Node current = last;
last = new Node();
last.ele = ele;
last.next = null;
if (current == null)
first = last;
else
current.next = last;
return this;
}
public Customer dequeue() {
if (isEmpty())
throw new java.util.NoSuchElementException();
Customer ele = first.ele;
first = first.next;
return ele;
}
public Customer peek() {
Customer ele = first.ele;
return ele;
}
You're using a linked-list to implement your queue. You can iterate over it just like you would iterate over any linked-list.
public void iterate() {
Node iterator = first;
while(iterator != null) {
Customer customer = iterator.ele;
// do something with the customer
iterator = iterator.next;
}
}
Edit: If your use case needs returning the iterator then ideally you should implement the Iterable interface. That solution is already mentioned in one other answer. For the sake of extending this answer to your use case I'm providing the below code. It would work, but its NOT an "Object-Oriented" way of doing it.
public class QueueLinkedList<Customer> implements Queue<Customer> {
private Node iterator;
// ...
public QueueLinkedList() {
iterator = null;
// ...
}
public Node iterator() {
iterator = first;
return iterator;
}
public boolean hasNext() {
return iterator != null;
}
public Node next() {
if(!hasNext()) {
throw new NoSuchElementException();
}
Node next = iterator;
iterator = iterator.next();
return next;
}
}
Usage:
QueueLinkedList queue = new QueueLinkedList();
// ...
Node iterator = queue.iterator();
while(queue.hasNext()) {
Node next = queue.next();
Customer customer = next.ele;
// do something with the customer
}
You need to implement Iterable<Customer> in your queue, as shown below, so that your queue can be iterated the same as arrays and other Java collections.
import java.util.*;
public class QueueLinkedList<Customer>
implements Queue<Customer>, Iterable<Customer>
{
Node first, last;
public class Node {
Customer ele;
Node next;
}
class Iter implements Iterator<Customer> {
Node current = first;
public boolean hasNext() {
return current != null;
}
public Customer next() {
if (!hasNext())
throw new NoSuchElementException();
Customer next = current.ele;
current = current.next;
return next;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public QueueLinkedList() {}
public boolean isEmpty() {
return first == null;
}
public QueueLinkedList<Customer> enqueue(Customer ele) {
Node current = last;
last = new Node();
last.ele = ele;
last.next = null;
if (current == null)
first = last;
else
current.next = last;
return this;
}
public Customer dequeue() {
if (isEmpty())
throw new java.util.NoSuchElementException();
Customer ele = first.ele;
first = first.next;
return ele;
}
public Iterator<Customer> iterator {
return new Iter();
}
}
Note that the way you have declared your class, Customer is a generic type parameter, not the class Customer. This is actually a good thing as it means you can use your QueueLinkedList class with any data type. To make it clear that Customer is a type parameter, you should replace every occurrence of Customer with a class variable name comprised of a single uppercase letter such as E.
Alternatively, if you want QueueLinkedList to always be a queue of Customer objects, you should change the class declaration to:
public class QueueLinkedList
implements Queue<Customer>, Iterable<Customer>
This is an example run in our Java class today with no problem but when I added the files into a new project I am having the following error. Can you please tell me if I have added files wrongly or maybe the professor was using an slightly different version of the files? Can you let me know what's the reason for this error and how to fix it?
The code for each of the file is as following: ArrayGSackIterable.java:
import java.util.Iterator;
public class ArrayGSackIterable<T> extends ArrayGSack<T> implements GSackIterableADT<T> {
public Iterator<T> iterator() {
return new ArrayGSackIterator<T>(items, numItems);
}
}
and for ArrayGSackIterator.java:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class ArrayGSackIterator<E> implements Iterator<E> {
private E[] items;
private int numItems, curr;
public ArrayGSackIterator(E[] gsackitems, int num) {
items = gsackitems;
numItems = num;
}
public boolean hasNext() {
return curr < numItems;
}
public E next() {
if (!hasNext()) throw new NoSuchElementException();
return items[curr++];
}
public void remove() {
}
}
and finally for GSackIterableADT.java:
import java.util.Iterator;
import java.util.NoSuchElementException;
public interface GSackIterableADT<T> extends Iterable<T> {
void add(T item);
T remove() throws NoSuchElementException;
boolean isEmpty();
Iterator<T> iterator();
}
UPDATE: Apparently I had to add these two files from another .zip file. GSackADT.java:
import java.util.NoSuchElementException;
public interface GSackADT<T> {
void add(T item);
T remove() throws NoSuchElementException;
boolean isEmpty();
}
ArrayGSack.java:
import java.util.NoSuchElementException;
public class ArrayGSack<T> implements GSackADT<T> {
// Internal storage and accounting members
protected T[] items;
protected int numItems;
private static final int INIT_SIZE = 100;
public ArrayGSack() {
items = (T[]) new Object[INIT_SIZE];
numItems = 0;
}
public void add(T item) {
if (numItems == items.length) expandStorage();
items[numItems++] = item;
}
public T remove() throws NoSuchElementException {
if (numItems < 1) throw new NoSuchElementException();
return items[numItems--];
}
public boolean isEmpty() {
return numItems == 0;
}
// Internal method to handle capacity issues
private void expandStorage() {
T[] oldItems = items;
items = (T[]) new Object[2 * items.length];
for (int i = 0; i < oldItems.length; i++)
items[i] = oldItems[i];
}
}
Your code is complaining for an unimplemented method remove from interface GSackIterableADT.
Your professor might have done either of these to make it run:
Deleted remove method from GSackIterableADT interface
Marked ArrayGSackIterable as an abstract class
I'm doing a learning exercise and creating my own linked list with an iterator. The class is as follows:
public class LinkedList<T> implements Iterable <T> {
private Node<T> head;
private Node<T> tail;
private int size;
public LinkedList() {
head = new Node<T>();
tail = new Node<T>();
head.setNext(tail);
tail.setPrevious(head);
size = 0;
}
public void append(T element) {
tail.getPrevious().setNext(new Node<T>(element));
tail.getPrevious().getNext().setNext(tail);
tail.getPrevious().getNext().setPrevious(tail.getPrevious());
tail.setPrevious(tail.getPrevious().getNext());
size++;
}
public void prepend(T element) {
head.getNext().setPrevious(new Node<T>(element));
head.getNext().getPrevious().setPrevious(head);
head.getNext().getPrevious().setNext(head.getNext());
head.setNext(head.getNext().getPrevious());
size++;
}
public void remove(Node<T> nodeToRemove) {
if(!isEmpty()) {
nodeToRemove.getPrevious().setNext(nodeToRemove.getNext());
nodeToRemove.getNext().setPrevious(nodeToRemove.getPrevious());
nodeToRemove.setNext(null);
nodeToRemove.setPrevious(null);
nodeToRemove.setElement(null);
nodeToRemove = null;
size--;
}
}
public boolean isEmpty() {
return size() == 0;
}
public int size() {
return size;
}
public Iterator<T> iterator() {
return new Cursor<T>(head);
}
public String toString() {
String result = "";
for(T t : this) {
result += t.toString() + "\n";
}
return result;
}
private final class Cursor<E> implements Iterator<E> {
private Node<E> current;
public <E> Cursor(Node<E> head) {
this.current = current;
}
public boolean hasNext() {
return current.getNext().getNext() != null;
}
public E next() {
current = current.getNext();
return current.getElement();
}
public void remove() {
remove(current);
}
}
}
After doing quite a bit of research it appears a good way to implement the iterator is to do it as an innner class. However, I'm getting a compile error with my remove method in the cursor class. I believe it's because of a type mismatch although the error I'm getting is remove() in LinkedList<T>.Cursor<E> cannot be applied to <Node<E>).
I've wrestled with this for quite some time and I can't understand what is wrong exactly, I would appreciate any insights you may have.
There are a few things wrong:
You have 2 methods called remove. Java thinks you are trying to call remove in the inner Cursor class which takes no parameters. You have to qualify the reference like this:
LinkedList.this.remove(current);
Your inner cursor class is non-static. Non-static inner classes are associated with the outer class instance that created them. Basically, they maintain a parent pointer to the outer class object. This is correct for implementing an iterator, but you need to change how you're using generics. Non-static inner classes can use the type parameters of their parent class. This means you can change your iterator definition to:
private final class Cursor implements Iterator<T>
and it will automatically use the <T> from LinkedList.
this.current = current; should probably be this.current = head;
Why does hasNext call getNext() twice?
Hope that helps.