Iterators and throwing exception - java

I am trying to make a double ended deque but I keep running into errors I frankly have no idea how to solve. The first one is regarding deque. In my iterator function, I keep getting the following error and I have no idea why:
Deque.java:105: error: incompatible types: Deque.DequeIterator cannot be converted to Iterator<Item>
return new DequeIterator();
Additionally, I have been trying to throw exceptions but haven't been able to for some reason. I keep getting errors such as the following:
Deque.java:72: error: cannot find symbol
throw java.util.NoSuchElementException();
^
symbol: class util
location: package java
Here is my code:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Deque<Item> implements Iterable<Item>{
private int size;
private Node<Item> first;
private Node<Item> last;
private class Node<Item>{
Item item;
Node<Item> next;
Node<Item> prev;
Node(Item item) {
this.item = item;
next = null;
prev = null;
}
}
// construct an empty deque
public Deque(){
first = null;
last = null;
size = 0;
}
public boolean isEmpty(){return size == 0;} // is the deque empty?
public int size(){return size;} // return the number of items on the deque
// add the item to the front
public void addFirst(Item item){
if (item == null){
throw new java.lang.NullPointerException();
}
else if (this.isEmpty()){
first = new Node(item);
first = last;
}
else{
Node oldfirst = first;
Node first = new Node(item);
first.next = oldfirst;
oldfirst.prev = first;
}
size ++;
}
// add the item to the end
public void addLast(Item item){
if (item == null){
throw new java.lang.NullPointerException();
}
else if (this.isEmpty()){
Node last = new Node(item);
last = first;
}
else{
Node oldlast = last;
Node last = new Node(item);
oldlast.next = last;
last.prev = oldlast;
}
size ++;
}
// remove and return the item from the front
public Item removeFirst(){
if (this.isEmpty()){
throw java.util.NoSuchElementException();
}
else{
Item item = first.item;
first = first.next;
first.prev = null;
if (size == 1){
first = last;
}
size --;
return item;
}
}
// remove and return the item from the end
public Item removeLast(){
if (this.isEmpty()){
throw java.util.NoSuchElementException();
}
else{
Item item = last.item;
last = last.prev;
if (size == 1){
last = first;
}
size --;
return item;
}
}
// return an iterator over items in order from front to end
public Iterator<Item> iterator() {
return new DequeIterator();
}
private class DequeIterator<Item> implements Iterable<Item>{
private Node current;
public DequeIterator() { this.current = first;}
public boolean hasNext(){ return current != null;};
public void remove() {throw new UnsupportedOperationException();}
public Item next(){
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
// unit testing (optional)
public static void main(String[] args){
Deque<String> deque = new Deque<String>();
deque.addFirst("1");
//StdOut.println("addfirst to string: " + deque.AXCToString());
deque.addFirst("2");
//StdOut.println("addfirst to string: " + deque.AXCToString());
deque.addFirst("3");
//StdOut.println("addfirst to string: " + deque.AXCToString());
deque.addFirst("4");
//StdOut.println("addfirst to string: " + deque.AXCToString());
deque.addFirst("5");
}
}

Your first issue is that your DequeIterator class implements Iterable, when it should implement Iterator. Iterable is usually used for things like collections, which can then provide an Iterator instance. It looks like you've already implemented the methods for Iterator, so this should just be a matter of changing the line to be:
private class DequeIterator<Item> implements Iterator<Item> {
For your second issue, you're missing the new keyword to construct the exception. It should be as follows:
throw new java.util.NoSuchElementException();
Additionally, it's standard practice in Java to use imports rather than using absolute paths, and it looks like you've already imported it, so you can shorten it to just this:
throw new NoSuchElementException();

Related

Java Deque Implementation Cannot convert Item

Deque implementation
I implemented a generic Deque data structure.
Please, review this implementation
and The error doesnt make sense to me, plz info me a little bit
import java.util.NoSuchElementException;
import java.util.Iterator;
public class Deque<Item> implements Iterable<Item>
{
private int n;
private Node first;
private Node last;
private class Node
{
private Item item;
private Node next;
}
private class ListIterator implements Iterable<Item>
{
private Node<Item> current = first;
public boolean hasNext()
{
return current != null;
}
public Item next()
{
if(!hasNext())
{
throw new NoSuchElementException("Deque underflow");
}
Item item = current.item;
current = current.next;
return item;
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
public Iterator<Item> iterator()
{
return new ListIterator();
}
public Deque()
{
n = 0;
first = null;
last = null;
}
// is the deque empty?
public boolean isEmpty()
{
return n ==0;
}
// return the number of items on the deque
public int size()
{
return n ;
}
// add the item to the front
public void addFirst(Item item)
{
if(item == null)
{
throw new IllegalArgumentException();
}
Node oldNode = first;
Node newNode = new Node();
newNode.item = item;
if(oldNode == null)
{
last = newNode;
}
else
{
newNode.next = oldNode;
}
first = newNode;
n++;
}
// add the item to the back
public void addLast(Item item)
{
if(item == null)
{
throw new IllegalArgumentException();
}
Node oldNode = last;
Node newNode = new Node();
newNode.item = item;
if(oldNode == null)
{
first = newNode;
}
else
{
oldNode.next = newNode;
}
last = newNode;
n++;
}
// remove and return the item from the front
public Item removeFirst()
{
if(isEmpty())
{
throw new NoSuchElementException("Deque underflow");
}
Item item = first.item;
first = first.next;
n--;
if(isEmpty())
{
first=null;
}
return item;
}
// remove and return the item from the back
public Item removeLast()
{
if(isEmpty())
{
throw new NoSuchElementException("Deque underflow");
}
Node secondLast = first;
if(n>3)
{
while(secondLast.next.next != null)
{
secondLast = secondLast.next;
}
}
else
{
secondLast = first;
}
Item item = last.item;
last = secondLast;
n--;
if(isEmpty())
{
last = null;
}
return item;
}
}
Test file
import java.util.Iterator;
public class dequeTest
{
public static void main(String[] args)
{
Deque<Double> d = new Deque<Double>();
System.out.println("Empty? "+d.isEmpty()+" \tSize is "+ d.size());
d.addFirst(2.0);
System.out.println(d.removeFirst());
System.out.println("Empty? "+d.isEmpty()+" \tSize is "+ d.size());
d.addFirst(1.2);
System.out.println(d.removeLast());
System.out.println("Empty? "+d.isEmpty()+" \tSize is "+ d.size());
d.addLast(1.4);
System.out.println("Empty? "+d.isEmpty()+" \tSize is "+ d.size());
for(int i = 0;i<10;i++)
{
d.addLast((double)i);
}
for(double value: d)
{
System.out.print(value);
}
}
}
Error
Type mismatch: cannot convert from Deque.ListIterator to Iterator
Can anyone help with the error? and fix it if you have a better idea
An Iterable<T> is not an Iterator<T>, but it has a method to get an Iterator<T>. Just change
public Iterator<Item> iterator()
{
return new ListIterator();
}
to
public Iterator<Item> iterator()
{
return new ListIterator().iterator();
}
beyond that, I would suggest you use an ArrayDeque (or even LinkedList) when you need a Deque. Your implementation does not appear to improve on either and worse your class name shadows the java.util.Deque interface (which you don't implement). Finally, a Deque should be a Collection (not just Iterable).

How to iterate over a Queue I implemented myself?

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>

Cannot instantiate the type Deque

import java.awt.HeadlessException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.xml.soap.Node;
public class Deque<Item> implements Iterable<Item> {
private int size;
private Node<Item> head;
private Node<Item> tail;
private static class Node<Item> {
private Item key;
private Node<Item> leftNode;
private Node<Item> rightNode;
Node(Item key, Node<Item> left, Node<Item> right) {
this.key = key;
this.leftNode = left;
this.rightNode = right;
}
}
public Deque() {
head = new Node<Item>(null,null,null);
tail = new Node<Item>(null,head,null);
head.rightNode = tail;
size = 0;
}
public boolean isEmpty() {
return head.rightNode == tail;
}
public int size() {
return size;
}
public void addFirst(Item item) {
if (item == null) throw new NullPointerException(" trying to add nothing");
else {
Node<Item> oldFirstNode = head.rightNode;
head.rightNode = new Node<Item>(item,head,oldFirstNode);
oldFirstNode.leftNode = head.rightNode;
size++;
}
}
public void addLast(Item item) {
if (item == null) throw new NullPointerException(" trying to add nothing");
else {
Node<Item> oldLastNode = tail.leftNode;
tail.leftNode = new Node<Item>(item,oldLastNode,tail);
oldLastNode.rightNode = tail.leftNode;
size++;
}
}
public Item removeFirst() { // remove and return the item from the front
if (isEmpty()) throw new NoSuchElementException(" Deque is alrady empty");
else {
Node<Item> delete = head.rightNode;
Node<Item> newFirstNode = head.rightNode.rightNode;
newFirstNode.leftNode = head;
head.rightNode = newFirstNode;
delete.leftNode = null;
delete.rightNode = null;
Item myKeyItem = delete.key;
delete = null;
size--;
return myKeyItem;
}
}
public Item removeLast() { // remove and return the item from the end
if (isEmpty()) throw new NoSuchElementException(" Deque is alrady empty");
else {
Node<Item> delete = tail.leftNode;
Node<Item> newLastNode = tail.leftNode.leftNode;
newLastNode.rightNode = tail;
tail.leftNode = newLastNode;
delete.leftNode = null;
delete.rightNode = null;
Item myKeyItem = delete.key;
delete = null;
size--;
return myKeyItem;
}
}
public Iterator<Item> iterator() { // return an iterator over items in order from front to end
return new DequeIterator();
}
private class DequeIterator implements Iterator<Item> {
private Node<Item> current = head.rightNode;
public boolean hasNext() {return current != tail;}
public void remove() { throw new UnsupportedOperationException("not yet"); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException("no next");
Item key = current.key;
current = current.rightNode;
return key;
}
}
public static void main(String[] args) {
Deque<Integer>[] s = new Deque[10];
for (int i = 0; i < 10; i++) {
s[i] =new Deque<Integer>(); // initial each object
}
s[0].addFirst(1);
// s[1].addFirst(2);
StdOut.print(s[0]);
//StdOut.print(s[1]);
}
}
In the following code I have a compiling error stats that "Cannot instantiate the type Deque".
package Assign3;
import java.util.Deque;
public class graph {
//private Deque<Integer>[] graphRepDeques;
final static int Amount = 200;
private Deque<Integer>[] s = new Deque[Amount];
public graph(String filename) {
In in = new In(filename);
//final int Amount = 200;
s = new Deque[Amount];
for (int i = 0; i < Amount; i++) {
String[] currentLine = in.readLine().split("\\s");
int size = currentLine.length;
s[i] =new Deque<Integer>(); // why Cannot instantiate the type Deque<Integer>???????
for (int j = 1; j < size; j++) {
int temp = Integer.parseInt(currentLine[j]);
s[i].add(temp);
}
}
}
private void show() {
for (int i = 0; i < Amount; i++) {
for (int a: s[i]) {
//StdOut.print(a + " ");
}
}
}
public static void main(String[] args) {
graph a = new graph("kargerMinCut.txt"); //whatever text you like with integers
a.show();
}
}
The error I got is
Cannot instantiate the type Deque<Integer>
I can instantiate Deque in the main function in class "Deque", but why I cannot do it in class "graph"? Very confused here
I appreciate any help thanks.
The goal of my code is to read the numbers
in a file line by line and for each line,
I store the numbers I got into a object of class Deque.
Therefore, I need an array of objects
of Deque to store all the numbers.
Similary to an array of linkedlist (Deque in my code).
The problem is I do not know how to initialized an array of this linkedlist (Deque in my code) properly so I can "push" all the keys in each linkedlist (Deque)
Since you applied Codebender's hint, you now just have to replace
s[i] = new Deque<Integer>();
with:
s[i] = new LinkedList<Integer>();
as you already mentioned in your question.
java.util.Deque is only an interface and therefore cannot be instantiated directly. All your variables (including the array) can still be of the type Deque and Deque[] respectively, since java.util.LinkedList implements that interface.
In your edited code, the problem is that you are just initializing the array. Not the Deque objects.
Deque<Integer>[] s = new Deque[10];
The above just creates an Array of 10 elements (and initializes all of them to null).
Hence s[0] is null, just like any other index. And you are trying to call addFirst(1) on null element.
So you should be initalizing each element in the array before using them,
s[i] = new Deque(); // In a loop if needed.

addFirst() method in Deque implementation

I am trying to implement a Deque in java using linked list. As a start I want to implement the method addFirst(). Here is the problem I am getting -- when I add few Strings, for example, "one", "two" and "three", it is inserting correctly, but when iterating the deque, it is only giving the last added object, not all the objects. Is there anything I am missing?
public class Deque<Item> implements Iterable<Item> {
private Node first;
private Node last;
private int N;
public Iterator<Item> iterator() { return new DequeIterator(); }
private class Node {
private Item item;
private Node next;
}
public Deque() {
first = null;
last = null;
N = 0;
}
public boolean isEmpty() { return first == null || last == null; }
public int size() { return N; }
public void addFirst(Item item) {
if (null == item) { throw new NullPointerException("Can not add a null value"); }
Node oldFirst = first;
first = new Node();
first.item = item;
first.next = null;
if (isEmpty()) {
last = first;
} else {
oldFirst.next = first;
}
N++;
}
private class DequeIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) { throw new NoSuchElementException(); }
Item item = current.item;
current = current.next;
return item;
}
}
public static void main(String args[]) {
Deque<String> deque = new Deque<String>();
deque.addFirst("one");
deque.addFirst("two");
deque.addFirst("three");
deque.addFirst("four");
for (String s : deque) {
System.out.println(s); // prints only "four"
}
}
}
Change oldFirst.next = first to first.next = oldFirst in addFirst() and it should work.
Right now first.next after addFirst() call isn't pointing to anything, as you're setting it to null. This causes the hasNext() method to return false, resulting in invalid iteration.
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Deque<Item> implements Iterable<Item> {
private Deque.Node first;
private Deque.Node last;
private int N;
public Iterator<Item> iterator() {
return new Deque.DequeIterator();
}
private class Node {
private Item item;
private Deque.Node next;
}
public Deque() {
first = null;
last = null;
N = 0;
}
public boolean isEmpty() {
return first == null || last == null;
}
public int size() {
return N;
}
public void addFirst(Item item) {
if (null == item) {
throw new NullPointerException("Can not add a null value");
}
if (first == null && last == null) {
first = new Node();
first.item = item;
first.next = null;
last = first;
} else {
Node node = new Node();
node.item = item;
node.next = first;
first = node;
}
N++;
}
private class DequeIterator implements Iterator<Item> {
private Deque.Node current = first;
public boolean hasNext() {
return current != null;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Item item = (Item) current.item;
current = current.next;
return item;
}
}
public static void main(String args[]) {
Deque<String> deque = new Deque<String>();
deque.addFirst("one");
deque.addFirst("two");
deque.addFirst("three");
deque.addFirst("four");
for (String s : deque) {
System.out.println(s); // prints only "four"
}
}
}
output :
four
three
two
one

inserting data after certain data (double linklist)

Hey, so I wanted to insert one data after the input data (not index).
I've tried but it always at the end, the data that i want to insert end up at the dront of the link list..
**public static void insertAfter(Object o,Object c){
Node newN = new Node();
Node help = new Node();
Node help2 = new Node();
newN.data = o;
help = head.next;
if(isEmpty()){
head = newN;
newN.next=head;
newN.prev=head;
}
else{
do{
help=help.next;
System.out.println(help);
}while(help.next!=head || !help.data.equals(c));
help2 = help.next;
newN.next = help2;
help2.prev = newN;
help.next=newN;
newN.prev=help;
}**
anyone could help?
thx a bunch!
What are the objects that you are comparing? if they are something other than string than you will have to override equals() method in order to get the correct comparison.
I think you should try another ending condition:
while(help.next!=head && !help.data.equals(c));
By the way, I can only advise you to avoid do...while without serious reasons, and to use getters and setters.
Your code should also be structured diffently. Why are you not writing a private method which just make the insert, i.e. your 5 last lines? Everything would be more readable and reusable.
Also, your variables need clear and meaningful names.
Do it yourself
I begun fixing your solution but ended writing a whole new implementation when wanting to test it... so here goes:
public class DoubleLinkedList<T> {
private class Node {
private Node prev;
private Node next;
private T data;
Node(T data) {
this.data = data;
}
}
Node head;
public boolean isEmpty() {
return head == null;
}
public void insertAfter(T afterThis, T objectToAdd) {
// cannot insert after in a empty list?!
if(isEmpty())
throw new NoSuchElementException("list is empty?");
// find the node where we want to insert the element
Node after = findNodeByObject(afterThis);
// create the node and update the links
addAfter(after, new Node(objectToAdd));
}
private void add(T objectToAdd) {
if (isEmpty()) {
head = new Node(objectToAdd);
head.next = head;
head.prev = head;
}
else {
addAfter(head.prev, new Node(objectToAdd));
}
}
private void addAfter(Node after, Node toAdd) {
Node afterAfter = after.next;
after.next = toAdd;
afterAfter.prev = toAdd;
toAdd.prev = after;
toAdd.next = afterAfter;
}
private Node findNodeByObject(T object) {
Node current = head;
while (true) {
if (current.data.equals(object))
return current;
if (current.next == head)
break;
current = current.next;
}
throw new NoSuchElementException("" + object);
}
#Override
public String toString() {
List<T> printList = new LinkedList<T>();
Node current = head;
while (true) {
printList.add(current.data);
if (current.next == head)
break;
current = current.next;
}
return printList.toString();
}
public static void main(String[] args) throws Exception {
DoubleLinkedList<String> list = new DoubleLinkedList<String>();
list.add("first");
list.add("third");
list.insertAfter("first", "second");
System.out.println(list);
}
}
Extend LinkedList
... and add the insertAfter method like this:
import java.util.LinkedList;
import java.util.ListIterator;
public class MyList<T> extends LinkedList<T> {
private void insertAfter(T first, T second) {
ListIterator<T> iterator = listIterator();
while (iterator.hasNext()) {
if (iterator.next().equals(first)) {
iterator.add(second);
return;
}
}
throw new IndexOutOfBoundsException("Could not find " + first);
}
public static void main(String[] args) throws Exception {
MyList<String> list = new MyList<String>();
list.add("first");
list.add("third");
list.insertAfter("first", "second");
System.out.println(list); // prints "[first, second, third]"
}
}

Categories

Resources