How to iterate over a Queue I implemented myself? - java

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>

Related

FIFO queue structure based on a singly linked list

In the java course I'm following right now, I'm required to implement a FIFO queue structure based on a singly linked list. I have to implement interface and override 3 methods: add, poll and peek.
I'm stuck with poll and peek and can not get an Object in return statement. Or may be there is another way to do it. For any help would be very grateful.
add -Use add() method to add elements into the Queue
poll - Fetching and removing the element at the head of the queue
peek- as pool without removing
public class Queue<T> implements Queue2<T> {
Node<T> head;
Node<T> tail;
int size;
#Override
public boolean add(T e) {
Node<T> node = new Node(e);
if (head == null) {
head = node;
tail = node;
} else {
tail.next = node;
tail = node;
node.next = null;
}
size++;
return true;
}
#Override
public T poll() {
if (size == 0)
return null;
else {
T obj = head.getObject();
head = head.next;
if (head == null) {
tail = null;
}
size--;
return obj;
}
}
#Override
public T peek() {
if (head == null)
return null;
else {
return head.getObject();
}
}
class Node<T> {
Node<T> next;
Node<T> value;
public <T> Node(T value) {
}
public T getObject() {
**return null;** // what should be returned here?
}
}
}
public static void main(String[] args) {
Queue<String> queue1 = new Queue<>();
queue1.add("finns");
queue1.add("bella");
queue1.add("ssara");
queue1.add("nanna");
queue1.add("anna");
System.out.println(queue1.peek());
System.out.println(queue1.poll());
class Node<T> {
Node<T> next;
T value;
public Node(T value) {
this.value=value;
}
public T getObject() {
return value;
}
}
The value in Node is your object so should be of type T , not Node<T>.
Remove the <T> from the constructor otherwise you are defining a new T and the assignment this.value=value; will not work.

Type T is not a valide Substitute for the bounded Parameter `<T extends Collection<?>>

package einfuehrung.knodenUndListeKopie;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class List<T> {
private class ListIterator<K> implements Iterator<T> {
private Node<T> node = null;
public ListIterator() {
node = head;
}
#Override
public boolean hasNext() {
return node.getNext() != null;
}
#Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
node = node.getNext();
T obj = node.getObject();
return obj;
}
}
public Iterator<T> iterator() {
ListIterator<T> iter = new ListIterator<T>();
return iter;
}
private Node<T> head;
public List() {
this.head = new Node<T>();
}
public Node<T> getHead() {
return head;
}
public void setHead(Node<T> head) {
this.head = head;
}
public boolean isEmpty() {
return head.getNext() == null;
}
public void addFirst(T element) {
Node<T> node = new Node<T>();
Node<T> nextNode = head.getNext();
node.setObject(element);
node.setNext(nextNode);
head.setNext(node);
}
public void addLast(T element) {
Node<T> node = new Node<T>();
Node<T> lastNode = head;
while (lastNode.getNext() != null) {
lastNode = lastNode.getNext();
}
lastNode.setNext(node);
node.setNext(null);
node.setObject(element);
}
public Object removeFirst() {
Object solution;
if (isEmpty()) {
solution = null;
}
Node<T> node = head.getNext();
Node<T> nextNode = node.getNext();
solution = node.getObject();
head.setNext(nextNode);
return solution;
}
public Object removeLast() {
Object solution;
if (isEmpty()) {
solution = null;
}
Node<T> beforeLastNode = head;
Node<T> lastNode;
while (beforeLastNode.getNext().getNext() != null) {
beforeLastNode = beforeLastNode.getNext();
}
lastNode = beforeLastNode.getNext();
solution = lastNode.getObject();
beforeLastNode.setNext(null);
return solution;
}
/**
* It does not delete the node, where the element is saved.
*
* #return first element of list
*/
public Object getFirstElement() {
return head.getNext().getObject();
}
}
First above is my List-Class.
package einfuehrung.knodenUndListeKopie;
import java.util.Collection;
public class Node<T extends Collection<?>> {
private Node<T> next;
private T object;
public Node() {
}
public Node(Node<T> next, T object) {
this.next = next;
this.object = object;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
public T getObject() {
return object;
}
public void setObject(T object) {
this.object = object;
}
public int countAllElements() {
int solution;
solution = object.size();
if (this.next != null) {
solution += this.next.countAllElements();
}
return solution;
}
}
Second Class is my Node-Class.
Problem Description. Everything was fine after i restricted the Parameter T in my Node Class. I had to, because T needed to implement the size-Method. It was necessary for the countAllElements() Method in Node-Class. In my List Class i get the error message : "Type T is not a valide Substitute for the bounded Parameter <T extends Collection<?>> of the type Node<T>. The error message appears everywhere where i use an instance of my object from the type Node<T>.
I hope i did everything Right in this Question by Posting my Code here. Sorry for my case-shift, i live in Germany. I dont know what my Computer does D:.
Edited: Sorry guys, i forgot to Change the title. I adjusted it.
As it stands, you are contradicting yourself: you are saying that your Nodes can contain any T in your List class, but your Node class says they can contain any Collection.
So, you either need to:
Go through all of the Node<T>s in the List class, replacing them with something list Node<Collection<T>>, Node<List<T>> etc
Remove the bound on the type parameter in the Node class, and supply a ToIntFunction<? super T> to the countAllElements method, to allow you to say "this is how you 'count' a T":
public int countAllElements(ToIntFunction<? super T> counter) {
int solution = counter.apply(object);
if (this.next != null) {
solution += this.next.countAllElements(counter);
}
return solution;
}

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).

Adding an element to a singly linked list in Java

I'm implementing a singly linked list in Java. What I don't like about this code is that I need to check if (head.next == null) every time I add an element. But the condition is met only once, when adding the first element.
Is there a way to implement a singly linked non-circular list without such a condition?
package sample;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class SinglyLinkedList<T> implements Iterable<T> {
private Node<T> head = new Node<T>(null);
private Node<T> last = null;
public SinglyLinkedList(T... elements) {
addAll(elements);
}
public void add(T element) {
if (head.next == null) {
head.next = new Node<T>(element);
last = head.next;
} else {
Node<T> newNode = new Node<T>(element);
last.next = newNode;
last = last.next;
}
}
public void addAll(T... elements) {
for (T element : elements) {
add(element);
}
}
#Override
public String toString() {
Iterator<T> iterator = iterator();
if (!iterator.hasNext()) {
return "[]";
}
StringBuilder builder = new StringBuilder();
builder.append("[");
while (iterator.hasNext()) {
T element = iterator.next();
builder.append(element);
if (!iterator.hasNext()) {
return builder.append("]").toString();
}
builder.append(", ");
}
return builder.toString();
}
#Override
public Iterator<T> iterator() {
return new Iterator<T>() {
Node<T> current = head;
#Override
public boolean hasNext() {
return current.next != null;
}
#Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Node<T> temp = current;
current = current.next;
return temp.next.element;
}
};
}
private static class Node<T> {
private Node<T> next;
private T element;
Node(T element) {
this.element = element;
}
#Override
public String toString() {
return element.toString();
}
}
}
You could initialize last to be pointing to head and then your if is redundant:
private Node<T> head = new Node<T>(null);
private Node<T> last = head;
public void add(T element) {
Node<T> newNode = new Node<T>(element);
last.next = newNode;
last = last.next;
}
There are many cases where "good OO design" allows you to go without if/else checks; most often by using some form of polymorphism.
Meaning: instead of asking some object about some property, to then make a decision on that in your client code, you somehow make sure that your client code can simply call a method on some other object. And then, the "if" is "hidden" within the code that initially generated that "other object" and gave it to your client code. (you find some nice examples how that works in these videos).
But - I think this would be clear overkill in this case!
The point is: from a readability point of view, that one check really doesn't hurt (you could refactor things into more methods maybe). And performance ... doesn't matter either. If your code is called so often that it would matter, the JIT will kick in anyway, and probably create code that that takes the correct branch directly for most cases.
Thus: this is a nice implementation; and I think you shouldn't worry about this one if-check there!

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