Making first object with a recursive class defination [duplicate] - java

This question already has answers here:
Java final modifier
(2 answers)
Closed 8 years ago.
I was experimenting a bit in java and stumbled across this problem
Suppose i have a class with this recursive defination
public class Node<T> implements Iterable<T>{
public final T element;
public final Node<T> next;
public Node(T head, Node<T> tail) {
this.element = head;
this.next = tail;
}
// Contains few more methods and implementation of iteratable like add, remove etc
}
Now, the thing is I will be using this class as a field in another class with final keyword. Now if in the beginning i would be making an empty list and then add it to the list, how should i proceed.
TO make it simple
class NodeList <T>{
private final Node<T> head;
public NodeList(){
}
// Few more functions
}
Using NodeList class how can i create an empty list and later on add data using add function

In java reference works as pointer to an object in memory that internally can point to another one in the same way.
Let's try to understand it visually:
What happens to the pointer head when the object obj is added to an empty linked list?
You have to remove final keyword from head because it's reference that changes every time when new node is added to point the new node.
In below snapshot head is a reference that point to first object in the memory and first object contains another reference next that points to second object and so on...
how should i proceed.
create a new node
point next of new node to next of head
point head to new node
Sample code:
class Node<T> {
public final T element;
public final Node<T> next;
public Node(T head, Node<T> tail) {
this.element = head;
this.next = tail;
}
}
class NodeList<T> {
private Node<T> head;
public void add(T value) {
if (head != null) {
Node<T> node = new Node<T>(value, head); // create a new node
head = node; // point `head` to new node
} else {
// if head is null then assign it to head
head = new Node<T>(value, null);
}
}
}
NodeList<String> nodeList = new NodeList<String>();
nodeList.add("First");
nodeList.add("Second");
nodeList.add("Third");
// print all nodes
Node<String> node = nodeList.head;
while (node != null) {
System.out.println(node.element);
node = node.next;
}
output:
Third
Second
First

You cannot do it with the final keyword on the head attribute, since it will force you to initialize it during the instanciation : you should then initalize it to null to represent the empty list and won't be able to append an element to it. Remove the final keyword, it has no use there.
I'm not even convinced of the use of final in your Node class. What if you want to add or remove an element in the middle of the list ? Using final there limits considerably the number of operations you can perform on your data structure.

Related

Understanding setup for doubly linked list in Java

I am working on a doubly linked list in Java. So that I can create functions, I'm first working to understand the setup.
I have this code. I have started comments with what each line does. Looking at tutorials and I want to make sure I understand this correctly. I still get a little confused on using classes.
If I create a new node by Node x = new Node(); - I am creating a new node of class Node. So that creates an instance using "static class Node {"
Each Node created contains a int item, Node next, and Node prev, that I will set in my functions. The int item I assume is the contents of the Node.
What does the line "public Node() {}" do?
public class MyDeque {
Node first = null; //instance variable, first is of type node and is set to null
Node last = null; //instance variable, last is of type node and is set to null
int N = 0; //keeping track of number of nodes
static class Node {
public Node() { }
public int item;
public Node next; //next is of type node
public Node prev; //prev is of type node
}
To understand this setup for Double-Linked-List you need to understand how a constructor works; A constructor is like a method, which is used to initialize properties of a class when the object of this class is initialized in memory for the first time.
Let's take your code for an example, I modified it in a proper way to understand why and how constructors used in Java -
public class MyDeque {
Node first;
Node last;
int N;
public MyDeque(){
this.first = null;
this.last = null;
this.N = 0;
}
static class Node {
int item;
Node next;
Node prev;
public Node() {
this.next = null;
this.prev = null;
}
public void setItem(int item) {
this.item = item;
}
public int getItem(){
return this.item;
}
// ... public getters for other items
}
As you can see two constructors public Node(){} and public MyDeque(){} are used to set values for the properties of those objects when they are initialized in memory for the first time.
Later, of course, you can set / unchange / change values of properties using the setter method or using the "." operator but remember constructor will always take place when the objects are initialized or reinitialized in memory for the first time.

Singly Linked List pass by value

Hi i am learning linked list in java. Its a simple doubt but couldn't figure out.
class Node{
int data;
Node next;
Node(int data){
this.data = data;
this.next = null;
}
//java main method
Node head = null;
Node newNode = new Node(1);
head.next = newNode;
Here i am passing the reference of the newNode to the next field in the Node class. The next is holding the reference of the newNode.
In dart programming languages objects are passed via call by value. By doing the above code is also working fine. My question is can we implement the Node field inside the Node class with either by reference or value.
In the context of c++, I don't know much c++ syntax but roughly it looks like this
//with pointer
class Node{
public:
int data;
Node* next;
}
It is possible to implement the above code like this one
//without pointer
class Node{
public:
int data;
Node next;
}
As stated by the other answers, your code wont work since your head variable is null and thus would throw a NullPointerException.
Your main method should like this:
Node head = new Node(0);
Node newNode = new Node(1);
head.next = newNode;
Java is always passing references by value. For a comprehensive answer see https://stackoverflow.com/a/40523/19799529
Pass-by-value
Java is always passing by value (as you are accustomed to):
int x = 3; f(x);
Object y = new Object(); g(y);
Above neither f nor g can alter the passed variables x and y.
The variables are just memory slots in which the value is stored, and that value is passed (not which memory slot), whether primitive type (int) or class instance (Object).
Linked list
Your Node class is fine.
public class SingleLinkedList {
Node head;
int count;
public int size() {
return count;
}
It is worth holding the Node inside a list class, possibly with a field for the number of elements. You could use that for index checking.
public void add(int i, int data) {
head = addToNodes(head, i, data);
++count;
}
private Node addToNodes(Node link, int i, int data) {
if (i <= 0 || link == null) {
Node node = new Node(data);
node.next = link;
return node;
}
link.next = addToNodes(link.next, i - 1, data);
return link;
}
Above I have used a recursive method. It shows that as the passed variable (head or some node's next field) cannot be changed in java, one has to return it assigning it to the same variable.
The code above is not very nicely formulated; write your own logic.

Storing One String Value in an empty LinkedList

public class LinkedListExplained {
public Node head;
public Node tail;
public int size;
public LinkedListExplained() { // Constructor
head = null;
tail = null;
size = 0;
}
public class Node{ // Inner Class
String value;
Node next;
}
public void add(String value){
Node node = new Node();
node.value = value;
size++;
if (head == null){
head = node;
tail = node;
return;
}
tail.next = node;
tail = node;
}
Question, when storing a single String value to an empty LinkedList, does it store the same value twice?
Once as head and once as tail?
No. The head and tail variables point to the same Node object. That object contains the String once.
If you are learning Java, the first and foremost thing you need to understand is that in Java, everything that looks like an object is never actually an object; it is a pointer to an object. And of course two pointers may point to the same object.
So, the statement public Node head; does not declare an instance of Node. It declares a pointer to an instance of Node. That's why you have to use new Node(); later.
So, since you set both the head and the tail pointers to point to the same instance of Node, it might appear that you have two copies of that node, but in fact you do not. You only have one instance of Node, and you have two pointers pointing at it.

How to find the first value in a linked list?

I have a linked list I'm given and I need to find the first value in the list via a getFirst method.I need to display an error message and quit the program if the value is null. The linked list is already given to me link so:
class MyLinkedList
{
private class Node // inner class
{
private Node link;
private int x;
}
//----------------------------------
private Node first = null; // initial value is null
//----------------------------------
public void addFirst(int d)
{
Node newNode = new Node(); // create new node
newNode.x = d; // init data field in new node
newNode.link = first; // new node points to first node
first = newNode; // first now points to new node
}
//----------------------------------
public void traverse()
{
Node p = first;
while (p != null) // do loop until p goes null
{
System.out.println(p.x); // display data
p = p.link; // move p to next node
}
}
}
//==============================================
class TestMyLinkedList
{
public static void main(String[] args)
{
MyLinkedList list = new MyLinkedList();
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
System.out.println("Numbers on list");
list.traverse();
}
}
Here's what I tried out for the method:
public static Node getFirst(Node list)
{
if (list == null)
{
System.out.println("Error!");
System.exit(1);
}
return MyLinkedList.first;
}
I know this isn't exactly right, we just started this in my class so I'm having trouble understanding what's going on with it. Thank you!
I think you should look at https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html and get an idea for the behavior of a linked list initially. Once you have an idea on how it behaves, you can think about how to add functionality around it. Right now you just have a single method which you call more than you should. What also might help is to create an interface and document it so you know what each method should do.
You should check that first isn't null in order to do what you describe in the question. Also, it is kind of weird that the first node autoreferences itself because usually it is left in null until you add another node
notice that the first value is linked to the first Node with is null. Then you have to check two things
Node == null (you got this)
Node.next == null (you have to do this)
When Node.next == null. It means that Node is first value because it is linked to the initial Node with is null.
Then you have
public static Node getFirst(Node list)
{
// if the list is empty
if (list == null)
{
System.out.println("Error!");
System.exit(1);
} else if(list.link == null) {
// this is the first value!
return list;
} else {
// keep searching recursive with the next Node
return getFirst(list.link);
}
}
The class MyLinkedList in your question follows the pattern of a stack data structure(At the time when i am writing this answer). That is: ever time you add a new element, the new element replaces the previously added element as the first element.
I guess you want to get 1 as your first element, if you have added elements 1,2,3 in that order. Correct me if i am wrong.
In that case your linked list and it's retrieval should be like this:
(Note: i have avoided private vars , public getter , settter , etc; to make code easily readable. But readers should add them.)
class Node{ int x; Node next; }
class LinkedList
{ Node head,tail;
void add(int y)
{ Node node = new Node();
node.x=y;
if(head==null)
head = tail = node;
else
tail = tail.next = node;
}
int getFirst()
{ if(head!=null)
return head.x;
else
throw new java.util.NoSuchElementException("List is empty");
}
}
If you look at java.util.LinkedList, you will find methods that are conventionally used in linked lists. If this is not a homework question, then i suggest you do not reinvent the wheel. Just use the existing libraries.
If you have to use the stack data structure, and you cannot change it, then i suggest you have to change your getFirst() like this:
int getFirst()
{ if(tail!=null)
return tail.x;
else
throw new java.util.NoSuchElementException("List is empty");
}
If you not allowed to add Node tail in your code, then your getFirst() will look like this:
int getFirst()
{ if(head==null)
throw new java.util.NoSuchElementException("List is empty");
Node node = head;
while(node.next!=null)
node=node.next;
return node.x;
}

Add to end of a doubly linked list

I am really struggling in adding a node at the end of a double linked list, adding to the head was easy, now I really can't find a way to add to the end. It seems stupid but I'm losing a lot of time, so if anyone can help that would be appreciated. Here's my partial implementation in Java.
public class DoublyLinkedList implements Iterable<Node>, Iterator<Node> {
private Node head = new Node();
private Node tail = head;
private Node current;
private Node previous;
#Override
public Iterator<Node> iterator() {
current = head;
previous = null;
return this;
}
public void addToHead(Node node) {
Node next = head.getNext(null);
Node previous = head.getNext(next);
head.setNext(previous, node);
node.setNext(null, head);
head = node;
}
#Override
public boolean hasNext() {
return current != tail;
}
#Override
public Node next() {
Node tmp = previous;
previous = current;
current = current.getNext(tmp);
return previous;
}
And here's Node Class
public class Node {
Node next = null;
Node previous = null;
Node getNext(Node node){
if(node == next){
return previous;
}
if(node == previous){
return next;
}
throw new IllegalStateException("something went wrong");
}
void setNext(Node node, Node next){
if(node == previous){
previous = next;
}
else if(node == this.next){
this.next = next;
}
else{
throw new IllegalStateException("something went wrong");
}
}
}
I hope you will understand the code above, basically I will need the following :
public void addToEnd(Node node) {
// implementation
}
What interface are you aiming to implement on this double-linked list? The way you've implemented getNext and setNext is not a clear way of doing it. If you only have one node, and you attempt to setNext with a null value for node, there is no way of telling unless you look at the code where your new node is going to end up. Along with that, I'm not sure if there is a nice way for you to set the previous node of a new tail node with the way you've implemented it. It's very ambiguous.
Can I recommend that you instead implement getNext(), setNext(Node), getPrevious() and setPrevious(Node) methods in your Node class? This would greatly simplify and clear up your code.
You would then be able to implement your addToEnd(Node) method very simply.
public void addToEnd(Node node) {
node.setPrevious(tail);
tail.setNext(node);
tail = node;
}
If you want to be able to iterate through the list in both directions using 'getNext()' and 'hasNext()', you could provide a forward or reverse Iterator implementation. There are examples of how to create Iterators floating around. The first answer on this question has an example of a reverse iterator.
The basic idea is just the same as adding at the beginning of the list.
We can split it up into two parts:
adding the item to the list
updating the head/tail-node of the list
In pseudocode:
node to_insert
//step 1
tail.setNext(to_insert)
to_insert.setPrevious(tail)
//step 2
tail = to_insert

Categories

Resources