Error in generic code - java

I am getting this error "Type mismatch: cannot convert from Object to E" in the last line of the pop() method.
Node
public class Node<E> {
E item;
Node next;
Node(E item) {
this.item = item;
this.next = null;
}
Node(E item, Node next) {
this.item = item;
this.next = next;
}
}
Stack
import java.util.NoSuchElementException;
public class Stack<E> {
private Node head;
private int size;
Stack() {
head = null;
size = 0;
}
public void push(E item) {
head = new Node (item, head);
size++;
}
public E pop() throws NoSuchElementException {
Node nodeToBePopped;
if (size == 0) {
throw new NoSuchElementException();
}
nodeToBePopped = head;
head = head.next;
size--;
return nodeToBePopped.item;
}
}
I don't understand why that error occurs despite item being declared as type E in the Node class. Why do I have to make an explicit cast in this instance?

This is the problem in Stack<E>:
private Node head;
and likewise later:
Node nodeToBePopped;
And in Node<E> itself:
Node next;
You're using the raw type Node here, so all the generics are lost, effectively. See the Java Generics FAQ for more information about raw types.
Just change the variable types to Node<E> and it should be fine.
I'd also recommend using private fields, and only declaring local variables at the point of first use - so your pop method would become:
public E pop() throws NoSuchElementException {
if (size == 0) {
throw new NoSuchElementException();
}
Node<E> nodeToBePopped = head;
head = head.next;
size--;
return nodeToBePopped.item;
}
Or in fact, just find the value to return from head before you change what head refers to:
public E pop() throws NoSuchElementException {
if (size == 0) {
throw new NoSuchElementException();
}
E previousHeadValue = head.item;
head = head.next;
size--;
return previousHeadValue;
}

Change the types of head and nodeToBePopped to Node<E>
This is because you have not specified that Stack<E> will have only elements of type Node<E>
Similarly change the push method and also the next variable in Node<E>.

Related

How to understand LinkedList?

An code instance of expressing the characters of LinkedList:
public class SimpleLinkedListTest {
private class Node{
public Node(Object o) {
this.o = o;
}
Object o;
Node next;
}
private Node first;
public void add(Object elem){
Node node = new Node(elem);
if (first == null) {
first = node;
} else {
append(node);
}
}
private void append(Node node){
Node last = first;
while(last.next != null){
last = last.next;
}
last.next = node;
}
}
The instance describes the "Chain characteristic" to encapsulating new Objects,how can I understand the "append" method in it?And what is the exact
"encapsulating process" LinkedList type performs?
LinkedList has two pointers first and last Node.
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
And Node class has two pointers next and previous:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
Now when you add new element to the end of list it takes last Node and uses its next reference to link it to new node that contains your element:
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
The same happens when you add element to beginning of list but this time it goes to Node first pointer.
And when you want to remove element it assigns null to Node next pointer of Node class.

Singly Linked List Implementation

Alright, I'm trying to implement a (Singly) Linked List via my textbook (Goodrich & Tamassia, Algorithm Design, 2001), and so far so good.
Now, the problem I'm running into, is that I cannot test it properly For example, if I would insert a node via my insertFirst method, how would I still be able to retrieve it to be able to use it for a method like swapElements?
I thought about working via elements, but then I'll run into problems when I have nodes with the same element. So, how should this work in general? I'm sorry if my question is relatively easy or vague, in that case please let me know how I can improve it as I'm fairly new to data structures.
Here's my code;
public class Node<E> implements Position<E> {
private Node<E> next;
private E element;
public Node(Node<E> next, E element) {
this.next = next;
this.element = element;
}
public Node(E element) {
this.element = element;
}
public void setNext(Node<E> next) {
this.next = next;
}
public Node<E> getNext() {
return next;
}
public void setElement(E element) {
this.element = element;
}
public E element() {
return element;
}
public String toString() {
return ("Element: " + element);
}
}
and
public class SinglyLinkedListImp<E> implements List<E> {
private Node<E> head;
private int size;
public SinglyLinkedListImp() {
this.head = null;
this.size = 0;
}
public Node<E> first() {
return head;
}
public Node<E> last() {
Node<E> current = head;
while (current.getNext() != null) {
current = current.getNext();
}
return current;
}
public boolean isFirst(Node<E> n) {
return (head == n);
}
public boolean isLast(Node<E> n) {
return (n.getNext() == null);
}
public Node<E> before(Node<E> n) {
Node<E> current = head;
while (current.getNext() != n) {
current = current.getNext();
}
return current;
}
public Node<E> after(Node<E> n) {
return n.getNext();
}
public Node<E> replaceElements(Node<E> n, E element) {
Node<E> current = head;
Node<E> previous = null;
while (current != n) {
previous = current;
current = current.getNext();
}
Node<E> newLink = new Node<E>(current.getNext(), element);
previous.setNext(newLink);
return current;
}
public void swapElements(Node<E> n, Node<E> k) {
E tmp = n.element();
n.setElement(k.element());
k.setElement(tmp);
}
public void insertFirst(E element) {
head = new Node<E>(head, element);
size++;
}
public void insertLast(E element) {
if (head == null) {
head = new Node<E>(head, element);
} else {
Node<E> current = head;
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(new Node<E>(null, element));
}
size++;
}
public void insertBefore(Node<E> n, E element) {
Node<E> current = head;
Node<E> previous = null;
while (current.getNext() != n) {
previous = current;
current = current.getNext();
}
previous.setNext(n);
}
public void insertAfter(Node<E> n, E element) {
Node<E> current = head;
while (current != n) {
current = current.getNext();
}
current.setNext(n);
}
public void remove(Node<E> n) {
Node<E> current = head;
Node<E> previous = null;
while (current != n) {
previous = current;
current = current.getNext();
}
previous.setNext(current.getNext());
size--;
}
public int size() {
return size;
}
public boolean isEmpty() {
return (size == 0);
}
public void display() {
if (head == null) {
System.out.println("Empty list.");
} else {
Node<E> current = head;
while (current != null) {
System.out.println(current.toString());
current = current.getNext();
}
}
}
}
Note that the SinglyLinkedListImp class is not totally done yet (some methods will give errors if the list is empty).
I don't think it's needed to provide the code for the two interfaces, but let me know if so.
In your implementation, you have set some methods (like getNext etc) that can be used in order to iterate the collection. A scenario that I can think of it is having retrieved any element of the list in one operation and then apply the editing on the collection based on the element (like swapElements) afterwards.
What I suggest you do though (and will probably make things clear) is add a retrieval method of an element by index:
a method get(int index) would return the element placed on the index given as argument. In fact, the LinkedList collection standard API in Java has such a method. The logic behind this is simple: get the next node till the iteration cycles number reaches the index number.
UPDATE: In order to apply element swapping, obviously the Nodes involved MUST be a part of the list, otherwise there is no meaning in this. As also suggested, swapElements might be basically used for in-class purposes, so unless you have a good reason for it, declare it private.

Singly Linked Circular List Add method

I am creating a singly linked circular list and I don't seem to understand why it is not working. Here is my code. Would someone help me and point out what am I doing wrong? I am able to add the first node but I don't understand how to add the second node. Could someone show me how to change it. I think my list is traversing endlessly that's why.
public class CircularList <E> {
private Node<E> head;
private class Node <E>
{
E data;
Node <E> next;
public Node(E data, Node<E> next)
{
this.data = data;
this.next = next;
}
public Node(E data)
{
this.data = data;
this.next = null;
}
}//node
public CircularList()
{
head = null;
}
public void add(E data)
{
Node <E> temp = new Node <E> (data);
if(head==null)
{
head=temp;
temp.next=temp;
System.out.println(head.next.data);
}
else
{
Node<E> temp2 = head.next;
while(temp2!=head)
{
if(temp2.next==head)
{
temp2.next=temp;
temp.next=head;
}
temp2=temp2.next;
}
}
}
Update your else part with this;
Node<E> temp2 = head;
while(temp2.next != head)
{
temp2=temp2.next;
}
temp2.next=temp;
temp.next=head;
If you would like to make your singly linked list circular, it would be a good idea to have a tail, then your code can be something along the lines of (pseudo code)
function addElement(data){
Node n = new Node(data)
if(list.isEmpty() ){
head = n
tail = n
n.setNext(n)
} else {
n.setNext(head)
tail.setNext(n)
head = n
}
}

Error parameter type E is hiding the type E

I am creating a generic linked stack. This error shows up when creating the new node shown next:
private class Node<E> {
What is wrong with my code that is causing this?
public class LinkedStack<E> implements StackBehavior<E> {
private class Node<E> {
private E element;
private Node<E> next;
private Node(E element) {
this.element = element;
this.next = null;
}
private Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
}
private Node<E> top = null;
public void push(E item) {
top = new Node<E>(item, top);
}
public E pop() {
if (top == null) {
throw new EmptyStackException("Pop error: Stack is empty.");
}
E item = top.element;
top = top.next;
return item;
}
public E peek() {
if (top == null) {
throw new EmptyStackException("Peek error: Stack is empty.");
}
return top.element;
}
public boolean isEmpty() {
return (top == null);
}
public String toString() {
Node<E> curr = top;
String stringStack = "top";
while (curr != null) {
stringStack += " --> " + curr.element;
curr = curr.next;
}
return stringStack;
}
}
In this declaration
public class LinkedStack<E> implements StackBehavior<E> {
you are declaring a new type variable named E.
In this inner class declaration
private class Node<E> {
you are declaring a new type variable also called E. Any use of Node.E inside Node hides the accessible type variable E declared in LinkedStack.
This is a warning, not an error, but consider changing names if you really need the type variable (but it doesn't seem like you do).
The problem is that <E> in Node<E> is hiding the <E> from top class LinkedStack<E>. There are two solutions for this:
Remove the <E> from the inner class. Usage of E inside it will automatically refer to the generic E in top class.
Make it an inner static class. This will make its generic E different from the E in top class.

Nodes, Queues, De-queues

I'm doing this small project of creating a queue and a de-queue in the same class along with using my own Node class and an interface.
The problem i'm facing is I've done all methods but can't get the method removeLast to work because i'm unable to let rear link to the node before it, after getting removed. Please help me with your suggestions? Thank you.
My node class.
public class Node<T> {
T info;
Node<T> next;
public Node(T element) {
info = element;
next = null;
}
public void setInfo(T element) {
info = element;
}
public T getInfo() {
return info;
}
public void setNext(Node<T> next) {
this.next = next;
}
public Node<T> getNext() {
return next;
}
}
My interface class
public interface DequeInterface<T> {
void addFront(T element);
void addLast(T element);
T removeFront();
T removeLast();
boolean isEmpty();
int getSize();
}
My deque class
import java.util.NoSuchElementException;
public class Deqeue<T> implements DequeInterface {
public Node<T> front;
public Node<T> rear;
int size;
public Deqeue() {
front = null;
rear = null;
size = 0;
}
#Override
public T removeFront() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = front.getInfo();
front = front.getNext();
size--;
return element;
}
#Override
public T removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = rear.getInfo();
size--;
return element;
}
#Override
public int getSize() {
return size;
}
#Override
public boolean isEmpty() {
return rear == null;
}
#Override
public void addFront(Object element) {
Node<T> newNode = front;
if (newNode == null) {
rear = front;
}
front = new Node(element);
front.setNext(newNode);
size++;
}
#Override
public void addLast(Object element) {
Node<T> newNode = rear;
if (newNode == null) {
front = rear;
}
rear = new Node(element);
newNode.setNext(rear);
size++;
}
}
The problem is that your list is singly-linked. Unfortunately, removing the last node of a singly-linked list requires traversing the entire list. Some alternatives:
you can make your list doubly-linked
you can use a random-access array instead of a linked list
you could use Okasaki's "purely functional datastructures" deque
You could have your Node have a reference to the previous Node as well. This would create a doubly linked list.
public class Node<T> {
T info;
Node<T> next;
Node<T> prev;
public Node(T element) {
info = element;
next = null;
prev = null;
}
public void setInfo(T element) {
info = element;
}
public T getInfo() {
return info;
}
public void setNext(Node<T> next) {
this.next = next;
}
public Node<T> getNext() {
return next;
}
public void setPrev(Node<T> prev) {
this.prev = prev;
}
public Node<T> getPrev() {
return prev;
}
}
Then in the Deque class change your removeFront and removeLast methods to account for prev
public T removeFront() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = front.getInfo();
front = front.getNext();
front.setPrev(null); //<<<--------------------------
size--;
return element;
}
#Override
public T removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = rear.getInfo();
rear.getPrev().setNext(null) //<<<--------------
rear=rear.getPrev(); //<<<--------------
size--;
return element;
}
And of course the addFirst and addLast methods have to be updated as well
#Override
public void addFront(Object element) {
Node<T> newNode = front;
front = new Node(element);
front.setNext(newNode);
if (newNode == null) {
rear = front;
}else{
newNode.setPrev(front);
}
size++;
}
#Override
public void addLast(Object element) {
Node<T> newNode = rear;
rear = new Node(element);
newNode.setNext(rear);
if (newNode == null) {
front = rear;
}else{
newNode.setNext(rear);
}
size++;
}
If you would not be allowed to change the code of Node and only can change the removeLast() method then you could do it like this:
#Override
public T removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = rear.getInfo();
if(rear==first){
rear=null;
first=null;
}else{
Node<T> prev = first;
while(prev.getNext()!=rear){
prev=prev.getNext();
}
rear=prev;
prev.setNext(null);
}
size--;
return element;
}
But this would be rather inefficient as it requires iterating through the whole list from the beginning.
Each node should have a pointer to the next node and to the previous node.
You can make your list doubly linked (extra management and opportunity for bugs), or you can iterate through the list every time you removeLast and set rear to the new last (much worse performance when removing from last especially on large lists.)
The easiest way to go about doing this is to implement a doubly linked list as opposed to a linked list. So your node class will need to keep track of the previous element. You will need to update your add functions to support this. Once completed, your remove last function will look like this:
#Override
public T removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
T element = rear.getInfo();
size--;
rear.getPrev().setNext(null);
rear = rear.getPrev();
return element;
}

Categories

Resources