Salve,
ho realizzato una lista concatenata con relativa classe iteratore ma non ho idea su come devo implementare l'iteratore per farlo funzionare.
La lista concatenata è:
package com_antomau_ListeConcatenate.LinkedList;
import com_antomau_ListeConcatenate.Studente.Studente;
import java.util.NoSuchElementException;
import com_antomau_ListeConcatenate.ListIterator.ListIterator;
public class ListaConcatenata {
//viene dichiarato quello che sarà un nodo della lista - esso contiene un oggetto di tipo studente e un collegamento al nodo successivo
public class Node
{
//variaibli contenute in ogni nodo della lista
Studente student;
public Node link; //collegamento al nodo successivo
} //end of Node class
//variabili
private Node headList; //nodo testa della lista
/**
* Metodo costruttore della classe: esso inizializza il nodo in testa alla lista
*/
public ListaConcatenata()
{
headList = null; //il nodo in testa alla lista viene inizializzato a null perché all'inizio dell'esecuzione del programma la lista è vuota
}
/**
* Questo metodo restituisce il nodo in testa alla lista
* @return Lo studente che si trova in testa alla lista, altrimenti null se la lista è vuota
*/
public Studente getFirst()
{
if (!(headList == null)) //if (headlist!=null)
{
return headList.student;
} //end of if
//throw NoSucheElementException();
return null;
} //end of firstToString method
public void removeFirst()
{
if (!(headList!=null)) //if (headList==null)
return;
else
{
headList = headList.link;
} //end of else
} //end of removeFirst
/**
* Questo metodo aggiunge un nodo in testa alla lista
* @param s Lo studente da aggiungere come oggetto del nodo della lista
*/
public void addFirst(Studente s)
{
System.out.println("debug current data = " + s.getSurname() + " " + s.getName() + " " + s.getSerial() + " " + s.getExamName() + " " + s.getExamVote()); //debug
Node newNode = new Node();
newNode.student = s;
newNode.link = headList;
headList = newNode;
} //end of addFirst
public void addLast(Studente s)
{
if (headList==null) addFirst(s);
else {
Node newNode = new Node();
newNode.student = s;
newNode.link = null;
Node current = headList;
Node previous = null;
while (current.link!=null)
{
previous = current;
current = current.link;
} //end of while
current.link = newNode;
} //end of else
} //end of addLast
//iteratore per la lista concatenata
/*
* Questo iteratore viene creato appositamente per la lista realizzata in questo programma
* pertanto i suoi metodi restituiranno studenti
* e coterranno riferimenti alle caratteristiche della lista attuale
* e/o dati pertinenti alla lista in questione
*/
public class LinkedListIterator implements ListIterator
{
//variabili
Node current; //riferimento al nodo corrente referenziato dall'iteratore
Node previous; //riferimento al nodo precedente a quello referenziato dall'iteratore
//
/**
* Questo è il costruttore della classe
*/
public LinkedListIterator()
{
current = null; //essendo un passaggio eseguito all'inizio dell'esecuzione del codice la lista e' vuota e pertanto il riferimento al nodo attuale e' null
previous = null; //per il medesimo motivo della linea precedente si inizializza questa variabile a null
} //end of builder
//
/**
* Questo metodo sposta l'iteratore nella posizione successiva della lista
*/
@Override
public Studente next()
{
previous = current; //il riferimento al nodo precedente assume il valore del nodo attuale
if (!hasNext()) throw new NoSuchElementException();
//
//l'obbiettivo e' scorrere la lista mediante un iteratore
if (!(current!=null)) //if (current == null)
current = headList; //se current e' uguale a null vuol dire che non referenzia nulla e quindi andra' a referenziare il nodo in testa alla lista
else current = current.link; // altrimenti il riferimento al nodo attuale diviene il nodo successivo a quello attuale
/*
* il metodo deve restituire quello che è divenuto l'elemento attuale
*/
return current.student;
} //end of next
//
/**
* Questo metodo verifica che esista un nodo successivo a quello attuale
* @return Vero se esiste un nodo successivo a quello attualmente referenziato, falso se questo non esiste.
*/
@Override
public boolean hasNext()
{
if (!(current!=null)) //if (current==null) //se il nodo corrente è nullo
return headList!=null; //restituisce il risultato dell'espressione (headList!=null): è vero se headList esiste, è falso se headList non esiste
else return current.link!=null; //se il nodo corente non è nullo - restituisce il riultato dell'espressione (current.link!=null): è vero se il nodo successivo a quello attuale esiste, è falso se il nodo successivo a quello attuale non esiste
} //end of hasNext
//
/**
* Questo metodo aggiunge un elemento alla lista.
* @param s Lo studente da aggiungere alla lista.
*/
@Override
public void add(Studente s)
{
if (!(current!=null)) { //if (current==null) //se il nodo current e' null vuol dire che la lista e' vuota
addFirst(s); //lo studente (oggetto) da aggiungere viene aggiuntom in testa alla lista chiamando il metodo addFirst
current = headList; //il riferimento al nodo corrente diviene il nodo in testa alla lista
} else {
Node newNode = new Node(); //viene creato un nuovo nodo
newNode.student = s; //l'oggetto (studente) del nodo divene s
newNode.link = current.link; //il nodo successivo a quello da aggiungere sara' il nodo successivo a quello attualmente referenziato
current = newNode; //il nodo attualmente referenziato diviene il nodo appena aggiunto
} //end of else
previous = current; //i riferimento al nodo precedente diviene il riferimento al nodo corrente per bloccare alcune operazioni in seguito descritte
} //end of add
//
/**
* Questo metodo rimuove un nodo della lista
*/
@Override
public void remove()
{
/*
* Come noi sappiamo da una lista non si puo' eliminare un nodo senza prima averlo referenziato
* oppure immediatamente dopo averne inserito uno
* oppure immediatamente dopo averne eliminato uno
* pertanto per fare si che cio' ia realizzabile in maniera corretta
* alla fine di ogni metodo che non puo' precedere l'eliminazione il riferimento al nodo precedente viene modificato al fine di referenziare il nodo attuale
* cosi', giunti a questo punto del programma, viene verificato il valore del riferimento al nodo precedente
* e se questo risulta essere uguale al nodo attuale viene lanciata un eccezione
*/
if (previous == current) throw new IllegalStateException();
else if (current == headList) removeFirst(); //se il nodo corrente fa riferimento al nodo in testa alla lista viene chiamato il metodo per l'eliminazione del nodo in testa alla lista
else previous.link = current.link; //altrimenti, se il nodo si trova in un altra posizione, il riferimento al nodo successivo del nodo precedente diviene il riferimento al nodo successivo al nodo attuale
/*
* per impedire l'eliminazione di un nodo immediatamente dopo che ne sia gia' stato eliminato uno
* viene imposto che previous e current siano uguali
* in questo caso, essendo appena stato eliminato il nodo corrente, il nodo corrente referenziera' il nodo precedente
*/
current = previous;
} //end of remove
//
/**
* Questo metodo modifica l'oggetto contenuto nel nodo attualmente referenziato
* @param s Lo studente da impostare come oggetto del nodo attuale
*/
@Override
public void set(Studente s)
{
if (!(current==null)) //if (current!=null)
current.student = s; //se current e' diverso da null il suo oggetto (student) viene modificato con quello passato al metodo
else //altrmenti, se current e' uguale a null
throw new NoSuchElementException(); //viene lanciata un eccezione in merito ad un oggetto inesistente
} //end of set
} //end of LinkedListIterator class
} //end of class
L'interfaccia per l'iteratore è:
package com_antomau_ListeConcatenate.ListIterator;
import com_antomau_ListeConcatenate.Studente.Studente;
public interface ListIterator {
public Studente next();
public boolean hasNext();
public void add(Studente s);
public void remove();
public void set (Studente s);
} //end of interface
La classe che definisce l'oggetto studente è:
package com_antomau_ListeConcatenate.Studente;
public class Studente {
//variabili
String surname;
String name;
int serialNumber;
String examName;
int examVote;
/**
* Builder
* @param s Surname
* @param n Name
* @param se Serial Number
* @param ne Exam's name
* @param ve Exam's vote
*/
public Studente(String s, String n, int se, String ne, int ve)
{
this.surname = s;
this.name = n;
this.serialNumber = se;
this.examName = ne;
this.examVote = ve;
}
/**
* @return Student's surname.
*/
public String getSurname()
{
return surname;
}
/**
* @retur Student's name.
*/
public String getName() {
return name;
}
/**
* @return Student's serial number.
*/
public int getSerial() {
return serialNumber;
}
/**
* @return Exam's name.
*/
public String getExamName() {
return examName;
}
/**
* @return Exam's vote.
*/
public int getExamVote() {
return examVote;
}
} //end of class
Il file contenente il metodo main è:
package com_antomau_ListeConcatenate.UserInterface;
import com_antomau_ListeConcatenate.Studente.Studente;
import com_antomau_ListeConcatenate.LinkedList.ListaConcatenata;
import com_antomau_ListeConcatenate.ListIterator.*;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Scanner;
import java.io.*;
public class UserListeConcatenate {
private static File file;
private static Scanner in;
private static ListaConcatenata myList;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(300, 300);
f.setLayout(new BorderLayout());
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel consolePanel = new JPanel();
consolePanel.setLayout(new GridLayout(4,3));
JButton exitButton = new JButton("Exit");
JButton openDBButton = new JButton("Open database");
JButton saveDBButton = new JButton("Save database");
JButton addToHeadListButton = new JButton("Add data to lsit's head");
JButton addToEndListButton = new JButton("Add data to list's end");
JButton printListButton = new JButton("Print all data");
JButton searchSurnameButton = new JButton("Search by surname");
JButton searchNumberButton = new JButton("Search by serial number");
JButton deleteSurnameButton = new JButton("Delete data by surname");
JButton deleteNumberButton = new JButton("Delete data by serial number");
JButton deleteHeadList = new JButton("Delete data in list's head");
JButton deleteEndList = new JButton("Delete data in list's end");
consolePanel.add(openDBButton);
consolePanel.add(saveDBButton);
consolePanel.add(exitButton);
consolePanel.add(addToHeadListButton);
consolePanel.add(addToEndListButton);
consolePanel.add(printListButton);
consolePanel.add(searchSurnameButton);
consolePanel.add(searchNumberButton);
consolePanel.add(deleteSurnameButton);
consolePanel.add(deleteNumberButton);
consolePanel.add(deleteHeadList);
consolePanel.add(deleteEndList);
JPanel contentPanel = new JPanel();
f.add(consolePanel, BorderLayout.NORTH);
f.add(contentPanel, BorderLayout.CENTER);
f.pack();
JFileChooser fileChooser = new JFileChooser(); //new fileChooser object
class openDBButtonListenerClass implements ActionListener {
@Override
public void actionPerformed (ActionEvent e) {
//open database and load data
fileChooser.showOpenDialog(f); //show new file chooser windows into frame f
try {
file = fileChooser.getSelectedFile(); //"file" become the file given by file chooser
in = new Scanner(file);
} catch(Exception exc) { //se si entra nel ramo catch stampa il log dell'errore e interrompi l'esecuzione del metodo corrente
exc.printStackTrace();
return;
} //end of try/catch
//String cognome, nome, esame;
//int matricola, vesame;
while (in.hasNext())
{
/*
cognome = in.next();
nome = in.next();
matricola = in.nextInt();
esame = in.next();
vesame = in.nextInt();
*/
Studente stud = new Studente(in.next(), in.next(), in.nextInt(), in.next(), in.nextInt()); //vengono acquisiti i dati e si fa in modo che lo scanner scorra verso la serie di token successiva (più token vengono scansionati insieme)
myList.addFirst(stud);
//add data to list here
//list.add(cognome, nome, matricola, esame, vesame);
//System.out.println("current data = " + stud.getSurname() + " " + stud.getName() + " " + stud.getSerial() + " " + stud.getExamName() + " " + stud.getExamVote()); //debug
} //end of while
}
}
ActionListener openDBButtonListener = new openDBButtonListenerClass();
openDBButton.addActionListener(openDBButtonListener);
class exitButtonListenerClass implements ActionListener {
@Override
public void actionPerformed (ActionEvent e) {
System.exit(0);
}
}
ActionListener exitButtonListener = new exitButtonListenerClass();
exitButton.addActionListener(exitButtonListener);
class printListButtonListenerClass implements ActionListener {
@Override
public void actionPerformed (ActionEvent e) {
//
}
}
ActionListener printListButtonListener = new printListButtonListenerClass();
printListButton.addActionListener(printListButtonListener);
} //end of main
} //end of class
Qualcuno potrebbe spiegarmi perché, come stanno le cose adesso, usando il metodo
addFirst il programma mi restituisce questo errore:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com_antomau_ListeConcatenate.UserInterface.UserListeConcatenate$1openDBButtonListenerClass.actionPerformed(UserListeConcatenate.java:103)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Grazie in anticipo a quanti mi risponderanno.