Why I am getting this output in my Java code? - java

The student at the top of the stack is Gullion,Hailey
Student Mcglothlen,Shizue is removed from the stack
Here are all the elements of the Stack using an Iterator
--------------------------------------------------------
Stack$Node#3012db7c
Stack$Node#2607c28c
Stack$Node#477588d5
Stack$Node#756a7c99
Stack$Node#221a5d08
Stack$Node#70d1c9b5
Stack$Node#5d11c3f0
Stack$Node#3956f14c
Stack$Node#7afbd1fc
null
Here are all the elements in the Stack
--------------------------------------
Putney,John
Larkey,Ismael
Winkler,Isiah
Aceto,Liana
Hamill,Crissy
Caraway,Elmira
Gullion,Hailey
Rodrigez,Jonie
Madruga,Terrell
Williams,Diego
The first list of elements of the Stack using an Iterator apparently is not working. I do not know why. Here is my code for Iterator in my Stack class:
public Iterator<Student> iterator() { return new ListIterator(); }
// an iterator, doesn't implement remove() since it's optional
private class ListIterator implements Iterator<Student> {
private Node<Student> current = top;
public boolean hasNext() {
return current != null;
}
public void remove() {
throw new UnsupportedOperationException();
#SuppressWarnings("unchecked")
public Student next() {
if (!hasNext()) throw new NoSuchElementException();
current = current.next;
return (Student)current;
}
}
Here is the code in my Driver class that is where there seems to be a problem:
System.out.println("\nHere are all the elements of the Stack using an Iterator");
System.out.println("--------------------------------------------------------");
Iterator <Student> iter = myStack.iterator();
while (iter.hasNext() )
System.out.println(iter.next() );
HERE IS ALL OF THE CLASSES:
Stack: http://pastebin.com/2HVLVHuM
Queue class: http://pastebin.com/3q537kHW
Student class: http://pastebin.com/UnBB7kPA
Driver class: http://pastebin.com/yeA34MNd
I CAN ONLY WRITE CODE IN THE STACK CLASS. The point of this was to Implement a stack using queues. Hope this helps

You need to add a toString() method in your Student class. The Iterator is working correctly, but the System.out.println() doesn't know how to display the Student.
Add something to the Student class like this...
public String toString(){
return name;
}
So that when you call System.out.println(), it can output a real value. When you call System.out.println(Object), it always tries to output the toString() value. If this method isn't defined, it will output the java ID of the object, which is what you're seeing.

current in your Stack iterator is defined as Node<Student>. You return current from your next() method using a cast.
So, next() returns a Node<Student> (type-cast to Student), instead of an actual Student. Since Node presumably doesn't have a toString method, you get the default output (Stack$Node#<addr>).
To fix, return something like current.item from next() instead (assuming that the item stored in the Node is called item).

First of all, see nneonneo 's answer for the incorrect cast in your next() method.
Secondly, your Iterator implementation is incorrect.
The next() function in your iterator returns the element current after setting it to current.next .
After calling next() on the last element of your iteration, hasNext() should return false. But it doesn't, because current still points to the element you just returned. So you will call next() again. And in this method, current = current.next will set current to null, and then return it. Which should not happen, since hasNext was true, right?
For the same reason, the fist elemtent of your stack is missing: You set current to the top element of your stack, but before outputting anything, you already switch to current = current.next. You should do that after doing the output.

The first list of elements of the Stack using an Iterator apparently is not working. I do not know why.
Because your iterator is returning a Node<Student> instead of a student. The problem is at:
return (Student)current;
You probably tried to do this, but got an Incompatible Type error:
return current;
So you tried to fix by casting. The problem is that a node is not a student. A node contains a student. You need to return the student that the node contains.
Try this:
return current.data;
No casting is required because the compiler knows that the "data" member of node is a Student, since you declared current of type Node<Student>. This will fix the problem where your student prints out incorrectly. However as pointed out by #Konstantin, your iterator is still broken. You need to save the value of current in a temporary variable, move current, then return the temporary variable. Here is one possible implementation:
public Student next() {
if (current == null) throw new NoSuchElementException();
Node<Student> result = current;
current = current.next;
return result.data;
}
[epilogue]
You really need to review the generics tutorial. It's not clear from the code you pasted in above but it's obvious in the paste-bin code that you are using Student as a type parameter. That is very non-standard and confusing. The convention is to use a capital letter - typically T. You should have declared stack like below. Everywhere you use Student, replace it with T.
public class Stack <T> implements Iterable<T>{ // good
instead of
public class Stack <Student> implements Iterable<Student>{ // bad
T means some type to be decided later and you can use Stack with any kind of object. Only when you actually create a stack to you use Student (or whatever)
public static void main(String [] args)
{
Stack<Student> x = new Stack<Student>();

Related

How to use Comparator<T> as an argument in a generic SortedDoublyLinkedList

I am currently working on an assignment for class where I am tasked with creating an empty List that has a Comparator as an argument then creating an add method for that sortedDoublyLinkedList where I am passed an argument and I have to iterate through the list to find where the new node fits. I'm not very familiar with Comparator so I'm a bit clueless as to how to add elements to my DoublyLinkedList because I cannot access the Comparator the way I though I was supposed to. Here is what I have now. Here is what I currently have.
public class SortedDoubleLinkedList<T> extends BasicDoubleLinkedList<T> {
Node<T> head=null;
Node<T> tail=null;
SortedDoubleLinkedList<T> sDLL;
public SortedDoubleLinkedList(Comparator<T> comparator2){
sDLL=new SortedDoubleLinkedList<T>(comparator2);
}
public SortedDoubleLinkedList<T> add(T data){
Node<T> newNode=new Node<T>(data);
//I have to iterate through the list and find where the new element data fits
if(head!=null&&tail!=null) {
Node<T> cursor=head;
while(cursor!=null) {
//the following code doesn't work
if(sDLL.comparator2.compare(data, cursor.getData())==0) {
}
}
}
else {
head=newNode;
tail=newNode;
}
return this; //return the SortedDoubleLinkedList<T>
}
Comparator is an interface. You need to implement a class that will provide that interface.
class Whatever implements Comparator<TYPE> {
int compare(TYPE a, TYPE b) {
... code to decide whether a is less than,
equal to, or greater than b ...
}
}
Where I wrote TYPE, you need an actual type. Just supplying the type variable T is not going to get you to runnable code, which I assume is your goal. Ultimately you've got to say what type will go in your list. So I'd be expecting something like (in your code above)
public class SortedDoubleLinkedList extends BasicDoubleLinkedList<String> {
where you're storing Strings in your list. And then TYPE in my code is also String.
ALTERNATIVELY
You can leave your SortedDoubleLinkedList generic (in terms of T) but ultimately you want to get concrete about it, maybe
SortedDoubleLinkedList<String> = new SortedDoubleLinkedList(new Whatever());
but the Comparator is still going to need to be a Comparator<String> (or whatever type you choose).

Issue creating iterator in java

I'm trying to create an iterator class that completes what I thought would be two simple methods but I am having issues I suppose creating the iterator. The line where I create the iterator is giving me a compile error saying "Iterator is abstract; cannot be instantiated". I am not too sure what that means, obviously I did something wrong though. Also I put the purpose of the methods above them, if you see anything wrong with them let me know. Thanks for any input!
import java.util.Iterator;
private class OrderedListIterator{
Iterator<E> it = new Iterator<E>();
//return true if iterator has more items
public boolean hasNext(){
boolean found = false;
if(it.hasNext == true)
found = true;
return found;
return found;
}
//return next item in the iterator
public E getNext(){
if(it.hasNext != false)
return it.next;
}
//prints out message
public void remove(){
System.out.println("Operation not supported");
}
}
The reason you are getting this error is because an iterator is an interface.
In the Java programming language, an interface is a reference type,
similar to a class, that can contain only constants, method
signatures, default methods, static methods, and nested types. Method
bodies exist only for default methods and static methods. Interfaces
cannot be instantiated—they can only be implemented by classes or
extended by other interfaces. Extension is discussed later in this
lesson.
From the Java docs https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html
An interface contains the definition of the methods, not the implementation and is why you can't create or call interfaces or it's methods. The iterator interface has two methods; hasNext() and next(). Your code looks like you intend to implement the iterator interface.
private class OrderedListIterator implements Iterator<E>
In your hasNext and next methods, you need to iterate over your OrderedList depending on how you have implemented it.
Here is an example of an iterator for an ArrayList which I have previously created.
private class ArrayIterator implements Iterator<E> {
private int arrayIndex = 0;
/**
* Checks if the set has a next value.
*
* #return true if there is a next value, else false
*/
public boolean hasNext() {
//Checks that the index is within the size of the ArrayList
return arrayIndex < size;
}
/**
* Gets the next value in the iteration.
*
* #return
* The next value in the list
* #throws NoSuchElementException
* if there is no next element in the list
*/
public E next() throws NoSuchElementException {
if (arrayIndex == size) {
throw new NoSuchElementException();
}
//Checks the ArrayList's data at the current index
return data[arrayIndex++];
}
}
Your private class is able to access the fields from it's surrounding class. In my example, the iterator stores an index (like an internal cursor) in the array and checks the ArrayList's data at the current index. Each time the next method is called, the index is increased for the next time.
If your OrderedList class is like a LinkedList and has nodes, you would save a reference to the node and each time the next method is called you would return the node, then change the cursor to the next node.

The method getFirst() is undefined for the type Queue<Vertex>

#Override
public Vertex next() {
Queue<Vertex> nV = new LinkedList<Vertex>(graph.getNeighbours(this.sV));
System.out.println(nV.getFirst());
return nV.getFirst();
}
Above I declare a queue nV which is a queue instantiated by a Linked List. A LinkedList type should have the method getFirst(), why won't this program allow it?? I'm ok with even using a pop since it's a queue if this is possible but not sure if that works either.
ERROR at solution.java (at line 42)
return nV.getFirst();
^^^^^^^^
The method getFirst() is undefined for the type Queue<Vertex>
I believe the method you're looking for is the peek method. The peek method returns the first element of the queue without removing it from the queue. However, if you do wish to remove the first element from the queue, then use the remove method, which dequeues an element from the queue.
Change nV.getFirst() to either nV.peek() or nV.remove()
You are assigning the LinkedList instance to a pointer of type Queue, that does not expose the getFirst() method, try with this:
#Override
public Vertex next() {
LinkedList<Vertex> nV = new LinkedList<Vertex>(graph.getNeighbours(this.sV));
System.out.println(nV.getFirst());
return nV.getFirst();
}
The LinkedList class implements the Queue interface, but the the getFirst() method is Inherited from the Deque, in fact, you could also do
Deque nV = new LinkedList<Vertex>(graph.getNeighbours(this.sV));
To have available the getFirst() method

Removing, Searching, and Returning a position using Type T

Need help defining these methods, I am not familiar using Type T.
Define the following two methods in the LinkedList class:
1) The searchItem method takes an item to be search of type T in the list and if it is found then returns the position in the list, otherwise return -1
2) The removeItem method takes as argument an item to be removed of type T and returns true if the item is successfully removed, otherwise returns false.
This sounds suspiciously like homework.
When you create a generic class in java you just need the class to have the on it.
public class LinkedList<T>
The T can be any letter you want it to be. It does not matter what you choose. Then when you create an instance of that class you will give it type t.
LinkedList<int> mylist = new LinkedList<int>();
This will create an instance of the linked list where everything that references T will be replaced with int.
So your methods just need to use type T.
public class LinkedList<T>
{
public int Search(T toSearch)
{
//search your nodes
return -1;
}
public boolean Remove(T toRemove)
{
//find item and remove if you can, return true
return false;
}
}
Just as a final note, returning a boolean for success is BAD. It is an exceptional case if the user tries to remove something that isn't in the list, and should throw an exception. Otherwise it does not need to return anything.

Node losing the reference to another object when passed through function

I'm working with double-ended queues for an assignment, and we're running into an issue where the object reference is disappearing from a node after being passed through an extremely simple method.
Some important definitions:
class Node {
String s;
Node prev;
Node next;
...
}
class Sentinel extends Node {
Node prev;
Node next;
//Constructor uses that of Node
}
class Deque {
Sentinel start;
...
}
One method we are writing removes a Node from a deque, based on the given string.
In deque:
public void removeSorted(String toRemove) {
// System.out.println(this.start);
// System.out.println(this.start.next);
this.start.next.removeSorted(toRemove);
}
The commented out println's show the correct Sentinel and Node.
Then, in Node:
public void removeSorted(String toRemove) {
if (this.s.equals(toRemove)) {
// System.out.println(this.prev);
// System.out.println(this.prev.next);
this.prev.next = this.next;
this.next.prev = this.prev;
} else if (this.s.compareTo(toRemove) > 0) {
throw new RuntimeException("String does not exist in these nodes!");
} else {
this.next.removeSorted(toRemove);
}
}
The println for this.prev outputs the Sentinel on the first recursion, as expected. However, this.prev.next outputs null instead of the Node.
This function only fails when trying to remove the first Node, directly after the Sentinel. If you try to remove any other Node, it works correctly, and trying to call this.prev.next results in a non-null answer.
Why does the reference disappear when passing to the function (immediately after), since we've shown that the reference is there directly before calling the function?
Either your question code is wrong, or you have same fields in both Node and in Sentinel. This means, that these two are different:
start.next is next field of Sentinel class, which hides field with same name from Node class.
start.next.prev.next is also a field of start, but now it is the field of Node class, because you access it through Node reference.
Remove prev and next from Sentinel. Actually remove the whole Sentinel, it looks like you use to to "remove" the String s, which is impossible, you can't "remove" super class fields. Or if you need/want sentinel, see below for alternative design.
Also, this demonstrates why you should use getters and setters instead of accessing fields directly... Your IDE probably has nice refactoring tool to add getters etc (right click on field, see "Refactor" submenu), use it! And if your IDE does not have that, switch to one which does (I prefer NetBeans, but Eclipse and IntelliJ are worthy too), writing Java without such an IDE is an exercise in masochism...
Also, in Java avoid that kind of inheritance. You should probably have this kind of overall design:
interface NodeInterface {...}
public class Node implements NodeInterface {...}
public class Sentinel implements NodeInterface {...}
Then in the NodeInterface, define getters and setters, which should take as parameters as well as return NodeInterface type. Sentinel class would not support all interface methods of course, so those methods can either return null;/do nothing, or throw new IllegalStateException("Sentinel does not support Xxxx."); depending on method and if calling that method for sentinel is bug in calling code or not (better start with throwing exception).
If this is school work and you have not gone over interfaces yet, then replace interface NodeInterface with class NodeBase (preferably abstract), but in "real world" this would be bad code, because Java does not support multiple inheritance.

Categories