How to retrieve a field value of an Object stored in a LinkedList?

Viewed 632

I am new to programming and get stuck with an access issue. Currently I try to exercise LinkedList - by creating one by myself and later use it.

I have 3 classes in the same directory - custom 'MyLinkedList', another custom one, that I called 'Month' and 'Main'. My idea is to creat 12 Objects of Month class, as each has 3 fields and add them to a LinkedList - I did it. Now I have problem, when I want to retrieve a certain value of a certain Oject's field. I get the address of the Object, but can't figure out, how to reach the value behind this address.

Example - I create a MyLinkedList with 12 Nodes and put an Object of type Month in every Node. Later I want to let's say get the field called 'season' of March(Object of type Month), which is stored in my Linked List.

What I do - access the field called "item" of my LinkedList, which field contains an Object(address of the Object) of type Month. Now I can't figure out, how can I proceed further, to reach the Object behind this address and retrieve the value, which the field of this Object keeps.

What I understand is - 1) I have a reference variable called 'myList' in the Stack, which contains address of Object of 'MyLinkedList' type in the Heap. 2) The place in the memory, corresponding to this adrress holds another 12 adresses of the 12 'Nodes'. 3) Each Node(piece of memory), holds the address of an Object 'Month'. 4) The place in the memory corresponding to Month's address holds the addresses of the 3 fields(of the Object). 5) Behind this last addresses(of the fields) there are placed the desired values. So I can only reach step 3, but cannot continue further. Would you advise how to proceed furhter.

I put some code of the 3 methods:

this is my code:

public class MyLinkedList {

    private class Node{

        Object item;
        Node next;

        Node(Object item){
            this.item = item;
            this.next = null;
        }

        Node(Object item, Node next){
            this.item = item;
            this.next = next;
        }
    }

    private Node head;
    private Node tail;
    private int count;

    public void addNode(Object element){
        Node newNode = new Node(element);
        if(head == null){
            head = newNode;
            head.next = tail;
            tail = head;
        }
        else {
            tail.next = newNode;
            tail = newNode;
        }
        count++;
    }
    
    public void printList(){
        Node currentNode = head;
        while(currentNode != null){
            if(currentNode.next != null){
                System.out.print(currentNode.item + ", ");
            }
            else {
                System.out.println(currentNode.item + ";");
            }
            currentNode = currentNode.next;
        }
    }
}
public class Month {

    private String season;
    private int length;
    public int index;

    public Month(int index){
        this.index = index;
    }

    public String getSeason(){
        return season;
    }

    public void setSeason(String season){
        this.season = season;
    }

    public int getLength(){
        return length;
    }

    public void setLength(int length){
        this.length = length;
    }
}
public class Main {
    public static void main(String[] args) {

        Month January = new Month(0);
        Month February = new Month(1);
        Month March = new Month(2);
        /*
        ....more of the same here
        */
        January.setLength(31);
        February.setLength(28);
        March.setLength(31);
        /*
        ....more of the same here
        */
        January.setSeason("Winter");
        February.setSeason("Winter");
        March.setSeason("Spring");
        /*
        ....more of the same here
        */

        MyLinkedList myList = new MyLinkedList();

        myList.addNode(January);
        myList.addNode(February);
        myList.addNode(March);
        /*
        ....more of the same here
        */

        System.out.println("Initially created list:");
        myList.printList();
        System.out.println();
        
}
3 Answers

Since item, in Node class, is of type Object, you need to cast it to Month before accessing any of the instance fields through the getter methods defined in the Month class.

Following code shows an example of how you can access the instance fields of the Month object at each node of the linked-list.

public void printList(){
    Node currentNode = head;

    while(currentNode != null){
        Month m = (Month) currentNode.item;
        System.out.println(m.getSeason());     // print season
        System.out.println(m.getLength());     // print length
        
        currentNode = currentNode.next;
    }
} 

Note: If you change the type of the item in Node class to Month, then you don't need to cast currentNode.item to Month before accessing its instance fields.

Alternatively, you could override the toString() method that returns the string representation of an instance of Month class. Doing this will allow you to just pass the instance of Month class to System.out.println() to print the details of that instance.

public class Month {
    ...
    
    @Override
    public String toString() {
        return "Season: " + this.season + "\nLength: " + this.length;
    }
}

Now, you can just do:

public void printList(){
    Node currentNode = head;

    while(currentNode != null){
        Month m = (Month) currentNode.item;
        System.out.println(m);              // print season and length
        
        currentNode = currentNode.next;
    }
} 

System.out.println(m); - this statement will print whatever is returned by toString() method that is overridden in Month class.

Again, if you change the type of item in Node class to Month, you wouldn't need to cast currentNode.item to Month. In that case, you can just do:

System.out.println(currentNode.item);             
        

First of all if you used generic MyLinkedList like MyLinkedList<Month> you would be able to get object of type Month from this kind of generic list right away without any casting.

In your particular case you have to explicitly cast the object of class Object back to class Month just like this: Month m = (Month)obj, where obj is an example item you get from MyLinkedList.

If it's just for printing purposes, I would suggest creating a toString() function for Month class and then just call it inside your printList() method.

toString method for Month class, generated by Intellij:

@Override
public String toString() {
    return "Month{" + index + ", " + season + ", " + length + '}';
}

But then again, your LinkedList contains Nodes, so you have to make toString() method for Node class too:

@Override
public String toString() {
    return item.toString();
}

And when you do all that, then just modify your printList() method:

public void printList(){
    Node currentNode = head;
    while(currentNode != null){
        if(currentNode.next != null){
            // call toString function
            System.out.print(currentNode.toString() + ", ");
        } else {
            System.out.println(currentNode.toString() + ";");
        }
        currentNode = currentNode.next;
    }
}
Related