Salve. Ho ricopiato da un libro i seguenti sorgenti che mi permettono di aggiungere e rimuovere dei valori da una lista concatenata:

codice:
package cap7;

class ListNode
{
	Object data;
	ListNode nextNode;
	
	ListNode (Object object)
	{
		this (object, null);
	}
	
	ListNode (Object object, ListNode node)
	{
		data = object;
		nextNode = node;
	}
	
	Object getObject ()
	{
		return data;
	}
	
	ListNode getNext ()
	{
		return nextNode;
	}
}

public class List
{
	private ListNode firstNode;
	private ListNode lastNode;
	private String name;
	
	public List ()
	{
		this ("list");
	}
	
	public List (String listName)
	{
		name = listName;
		firstNode = lastNode = null;
	}
	
	public void insertAtFront (Object insertItem)
	{
		if (isEmpty ())
		{
			firstNode = lastNode = new ListNode (insertItem);
		}
		else
		{
			firstNode = new ListNode (insertItem, firstNode);
		}
	}
	
	public void insertAtBack (Object insertItem)
	{
		if (isEmpty ())
		{
			firstNode = lastNode = new ListNode (insertItem);
		}
		else
		{
			lastNode = lastNode.nextNode = new ListNode (insertItem);
		}
	}
	
	public Object removeFromFront () throws EmptyListException
	{
		if (isEmpty ())
		{
			throw new EmptyListException (name);
		}
		
		Object removedItem = firstNode.data;
		
		if (firstNode == lastNode)
		{
			firstNode = lastNode = null;
		}
		else
		{
			firstNode = firstNode.nextNode;
		}
		
		return removedItem;
	}
	
	public Object removeFromBack () throws EmptyListException
	{
		if (isEmpty ())
		{
			throw new EmptyListException (name);
		}
		
		Object removedItem = lastNode.data;
		
		if (firstNode == lastNode)
		{
			firstNode = lastNode = null;
		}
		else
		{
			ListNode current = firstNode;
			
			while (current.nextNode != lastNode)
			{
				current = current.nextNode;
			}
			
			lastNode = current;
		}
		
		return removedItem;
	}
	
	public boolean isEmpty ()
	{
		return firstNode == null;
	}
	
	public void print ()
	{
		if (isEmpty ())
		{
			System.out.printf ("Empty %s\n", name);
			return;
		}
		
		System.out.printf ("The %s is : ", name);
		ListNode current = firstNode;
		
		while (current != null)
		{
			System.out.printf ("%s ", current.data);
			current = current.nextNode;
		}
		
		System.out.println ("\n");
	}
}
codice:
package cap7;

public class EmptyListException extends RuntimeException
{
	public EmptyListException ()
	{
		this ("List");
	}
	
	public EmptyListException (String name)
	{
		super (name + " is empty");
	}
}
codice:
import cap7.*;

public class ListTest
{
	public static void main (String[] args)
	{
		List list = new List ();
		
		list.insertAtFront (-1);
		list.print ();
		list.insertAtFront (0);
		list.print ();
		list.insertAtBack (1);
		list.print ();
		list.insertAtBack (5);
		list.print ();
		
		try
		{
			Object removedObject = list.removeFromFront ();
			System.out.printf ("%s removed\n", removedObject);
			list.print ();
			
			removedObject = list.removeFromFront ();
			System.out.printf ("%s removed\n", removedObject);
			list.print ();
			
			removedObject = list.removeFromBack ();
			System.out.printf ("%s removed\n", removedObject);
			list.print ();
			
			removedObject = list.removeFromBack ();
			System.out.printf ("%s removed\n", removedObject);
			list.print ();
		}
		catch (EmptyListException e)
		{
			e.printStackTrace ();
		}
	}
}
Il programma funziona perfettamente, ma quello che non mi è chiaro è: quando vengono stampati tutti gli oggetti concatenati, noi ci spostiamo prendendo come riferimento solo firstNode. Ora, come è possibile che utilizzando solo quello, riusciamo a stampare anche i valori di lastNode? Eppure sono due oggetti diversi!