PDA

View Full Version : [JAVA] Problema di accesso ad una variabile privata e sollevo eccezione


YSN
22-01-2010, 10:35
Salve ci ho questo esercizio da svolgere:

È necessario scrivere un’applicazione Java che consenta di effettuare la gestione dei dati relativi agli iscritti di
una scuola militare. Ciascun iscritto, rappresentato da una matricola (di 5 cifre, es. ‘23678’), nome e cognome,
può frequentare i corsi annuali della scuola. Ciascun corso è caratterizzato da un codice identificativo unico, la
denominazione, la data di inizio e di fine, e prevede una esercitazione pratica. L’esercitazione può svolgersi in
un campo militare, che è a sua volta caratterizzato da un nome e un indirizzo (es. ‘Campo Seagate’, ‘Via del
Tronto, 23 - Bari’), e da una serie di attrezzature che servono per lo svolgimento dell’esercitazione stessa (es.
‘Paracadute’, ‘Tuta mimetica’, ‘Elicottero’ etc.).

1--Utente inserisce iscritti ai corsi da input
2--Utente visualizza esercitazioni per iscritto
3--Utente restituisce l’iscritto che ha partecipato al numero più alto di esercitazioni con il paracadute;
4--Utente cerca per ogni attrezzatura usata nelle esercitazioni gli iscritti che l’hanno usata

io ho proceduto in questo modo:
1--ho dichiarato una classe di nome "Iscritto".
2--ho dichiarato un'altra classe di nome "Corso", nella quale ho dichiarato le variabili : (codiceCorso, nomeCorso, dataInizio, dataFine, nomeCampo, indirizzo, attrezzature e una collezione di Iscritto "ArrayList<Iscritto>")
3--ho dichiarato una classe di nome Scuola, nella quale ho messo i vari metodi che implamentano i casi d'uso.
il primo metodo che mi permette l'inserimento degli iscritti, i corsi e le esercitazioni. e FUNZIONA
ho implementato un secondo metodo che mi permette di stampare tutti gli iscritti coi relativi corsi e FUNZIONA

il problema inzia quando devo implamentare il metodi che mi permette di visualizzare l'esercitazione per iscritto.

public void stampaEserc(String matricola){

if(lista.size() == 0){
System.out.println("Lista vuota");
} else {
for(int i = 0; i < lista.size(); i++){
if(lista.get(i).getIscritto().get(i).getMatr().equals(matricola)){
System.out.println("Nome campo eserc. : " + lista.get(i).getNomeCampo() + "\n" +
"Indirizzo campo : " + lista.get(i).getIndir() + "\n" +
"Attrezzature util. : " + lista.get(i).getAttrezz() + "\n");
}
}
}
}

praticamente il metodo deve cercare di la matricola e se la trova deve stampare a video le esercitazioni a cui ha partecipato.

Quando al metodo passo la matricola mi stampa solo la prima esercitazione e poi solleva un'eccezione di tipo IndexOutOfBoundsException.

non so il perchè?

help me please, sono disperato...

se volete che vi mostro tutto il codice non è un problema

vladix
22-01-2010, 11:22
if(lista.get(i).getIscritto().get(i).getMatr().equals(matricola))

e qui che scatta l'eccezzione IndexOutOfBoundsException. Tu hai 2 liste : la prima e la variabile lista e la seconda e lista e il risultato del metodo getIscritto ( o almeno cosi sembrerebbe da come hai scritto ) .
Il tuo problema e che usi lo stesso index per tutte e due le liste senza preoccuparti di quanti elementi ci sono nella seconda lista . per come hai fatto tu la seconda lista dovrebbe essere valorizatta in questo modo

index 0 contiene un elemento
index 1 contiene due elementi
index 3 contiene 3 elementi e cosi via , e a ogni ciclo ti visualizza la posizione "index" della seconda lista e se nn c'e va in errore.

La cosa da fare e ciclare anche sulla seconda lista .

YSN
22-01-2010, 11:42
per intenderci ti scrivo il codice:
Questa è la classe CorsoEserc:
public class CorsoEserc{

private ArrayList<Iscritto> iscritto = new ArrayList<Iscritto>();
private String codCso;
private String denomin;
private String dataIn;
private String dataFn;
private String nomeCampo;
private String indir;
private String attrez;

//Nel costruttore ho inizializzato tutti i campi istanza, e all'ArrayList ho aggiunto un iscritto
public CorsoEserc(Iscritto i, String codCso, String denomin, String dataIn, String dataFn,
String nomeCampo, String indir, String attrez){

iscritto.add(i);
this.codCso = codCso;
this.denomin = denomin;
this.dataIn = dataIn;
this.dataFn = dataFn;
this.nomeCampo = nomeCampo;
this.indir = indir;
this.attrez = attrez;
}
public void setIscritto(ArrayList<Iscritto> iscritto){
this.iscritto = iscritto;
}

public void setCodCso(String codCso){
this.codCso = codCso;
}
...........
il resto del codice sono metodi sete get dei campi istanza//
}



//Questa è la classe Iscritto
public class Iscritto{

private String matr;
private String nome;
private String cognome;

public Iscritto(){
this.matr = "";
this.nome = "";
this.cognome = "";
}

public Iscritto(String matr, String nome, String cognome){
this.matr = matr;
this.nome = nome;
this.cognome = cognome;
}
...................
//Il resto del codice sono metodi set e get dei campi istanza
}

//Questa è la classe Scuola nella quale ci sono i vari metodi
public class Scuola{

private ArrayList<CorsoEserc> lista = new ArrayList<CorsoEserc>();

//Questo è il metodo d'inserimento FUNZIONA
public void inserisci(String matr, String nome, String cognome, String codCso, String denomin,
String dataIn, String dataFn, String nomeCampo, String indir, String attrez){

Iscritto iscr = new Iscritto(matr, nome, cognome);
CorsoEserc csoEs = new CorsoEserc(iscr, codCso, denomin, dataIn, dataFn, nomeCampo, indir, attrez);

lista.add(csoEs);
}

public String stampaCE(CorsoEserc ce){
return ce.toString();
}

//Ho implemetato questo metodo per poter verifivare l'esattezza dell'inserimento e FUNZIONA
public void stampa(){
if(lista.size() == 0){
System.out.println("Lista vuota");
} else {
for(int i = 0; i < lista.size(); i++){
System.out.println(lista.get(i).getIscritto().toString() + stampaCE(lista.get(i)));
System.out.println();
System.out.println();
}
}
}

/*
Qua inizia il problema perchè devo accedere alla variabile private matricola della classe Iscritto
riesco ad accedere così("tmp.getIscritto().get(i).getMatr()")e va bene, ma questo metodo, mi stampa solo la prima esercitazione
e poi mi solleva la famosa eccezione "IndexOutOfBoundsException" e l'applicazione si conclude.

*/

public void stampaEserc(String matricola){
CorsoEserc tmp = null;
if(lista.size() == 0){
System.out.println("Lista vuota");
} else {
for(int i = 0; i < lista.size(); i++){
tmp = lista.get(i);
if(tmp.getIscritto().get(i).getMatr().equals(matricola)){
System.out.println("Nome campo eserc. : " + lista.get(i).getNomeCampo() + "\n" +
"Indirizzo campo : " + lista.get(i).getIndir() + "\n" +
"Attrezzature util. : " + lista.get(i).getAttrezz() + "\n");
}
}
}
}

}

Mi spieghi più meno come devo procedere, può darsi anche che l'implentazione iniziale del codice è errata
Grazie davvero

khelidan1980
22-01-2010, 13:26
ma getIscritto cosa ritorna?Perche ci fai un nuovo get di sopra?
Poi usa il tag code che non si capisce niente, quel metodo non lo mica trovato

YSN
22-01-2010, 22:40
Siccome iscritto è private, per accederci ho pensato a:
public ArrayList<Iscritto> getIscritto(){
return this.iscritto;
}

clockover
22-01-2010, 23:41
Siccome iscritto è private, per accederci ho pensato a:
public ArrayList<Iscritto> getIscritto(){
return this.iscritto;
}

Non ho letto il codice completo ma questa parte, anche se giusta, non andrebbe fatta!

Eseguendo return this.iscritto;
tu dai la possibilità al cliente di modificare a suo piacimento quella lista!

E' conveniente invece return this.iscritto.clone();

Ha proprio la faccia di un esercizio di progettazione in UML!

P.S.
leva quei colori e definisci un tag code per ogni classe, si legge sicuramente meglio!

YSN
26-01-2010, 10:05
allora io comunque ho proceduto su suggerimento di vladix, infatti siccome uso lo stesso indice per entrambe le liste, solleva leccezione.ho fatto un ciclo nidificato e ora mi funziona.
public void ricercaEsPerIscritto(String matricola){
CorsoEserc tmp = null;
if(lista.size() == 0){
System.out.println("Lista vuota");
} else {
int conta = 0;
for(int i = 0; i < lista.size(); i++){
tmp = lista.get(i);
for(int j = 0; j < tmp.getIscritto().size(); j++){
if(tmp.getIscritto().get(j).getMatr().equals(matricola)){
conta++;
}
}
}
if(conta > 0){
for(int i = 0; i < lista.size(); i++){
tmp = lista.get(i);
for(int j = 0; j < tmp.getIscritto().size(); j++){
if(tmp.getIscritto().get(j).getMatr().equals(matricola)){
stampaEsercitazione(i);
}
}
}
} else {
System.out.println("Errore");
}
}
}
mi manca solo il caso d'uso 3 "Utente restituisce l’iscritto che ha partecipato al numero più alto di esercitazioni con il paracadute".

che non ho la più pallida idea come devo procedere...

banryu79
26-01-2010, 10:17
Usare il colore verde per evidenziare il codice non e' stata una bella idea... i miei bulbi occulari già privi del giusto sonno sono stati a rischio esplosione dopo 5 sec...

Comunque, nel metodo getIscritto() (che dal nome uno potrebbe legittimamente supporre di ricevere un Iscritto, non una lista di oggetti) invece di restituire il riferimento alla lista stessa si può restituire un riferimento ad una "vista" di quella lista:

public ArrayList<Iscritto> getIscritto(){
return Collections.unmodifiableList(this.iscritto);
}

Il chiamante può usare la "vista" per consultare la lista, ma se prova a modificarla (sia direttamente che usando l'iteratore prodotto tramite la vista restituita) parte in quarta una UnsupportedOperationException.