PDA

View Full Version : [JAVA] Collezione omogenea di oggetti relazionabili...sono in crisi con un metodo...


Rintrah84
09-07-2009, 10:16
Ciao,
stò tentando di rifare il compito d'esame su cui sono stato bocciato la volta scorsa...ma ho dei problemi (HELP ME...il nuovo appello si avvicina).

Allora i primi 2 punti chiedono:


Si richiede la possibilità di rappresentare e gestire una collezione omogenea e dinamica di oggetti generici
per i quali è possibile definire una generica relazione booleana: due oggetti possono essere oppure non
essere in relazione.

1) Si richiede l’implementazione del tipo CollezioneConRelazione mediante la classe Java
CollezioneConRelazione.

2) Sia definito un operatore di accesso in lettura (osservatore) che, a partire da un dato parametro, opera come segue:
· se la collezione contiene elementi in relazione con il parametro, l’operatore calcola un iteratore che enumera tutti gli elementi della collezione che sono in relazione con tale parametro;
· qualora la collezione non contenga elementi in relazione con il parametro, l’operatore calcola il primo elemento della collezione.


Mi sono completamente bloccato sul punto numero 2 (qualche idea peròla ho...anche perchè avevo parlato con persone che erano riuscite a passare l'esame e mi avevano dato qualche idea).


Io perora ho fatto così:

Per prima cosa definisco l'interfaccia Relazionabile che mi definisce tipi di dati generici che come unico comportamento comune hanno quello di saper rispondere se due oggetti sono in relazione tra loro:


/** OVERVIEW: Si tratta di un'interfaccia che descrive oggetti generici che hanno come caratteristica comune quella di
sapere se due oggetti sono in relazione tra loro */

public interface Relazionabile{

boolean isInRelation(Relazionabile r);
}


Poi ho definito la classe CollezioneConRelazione che mi rappresenta la mia collezione omogenea e dinamica di Relazionabili. Per essere omogenea i dati dentro la collezione devono avere tutti lo stesso tipo effettivo. Per fare questo il metodo insert() si comporta così: Se la collezione è vuoto --> inserisce al suo interno un qualsiasi oggetto Relazionabile; Se nella collezione è presente almeno un oggetto --> Prima di inserire un oggetto parametro controlla che esso abbia lo stesso tipo effettivo degli oggetti nella collezione (viene controllato che abbia lo stesso tipo effettivo del primo elemento della collezione...così da inserire solo elementi con lo stesso tipo effettivo del primo oggetto inserito nella collezione).

E fin quà sono sicuro che va tutto bene:


import java.util.*;

/** OVERVIEW: La classe implementa una collezione omogenea (cioè contenente dati aventi tutti lo stesso tipo effettivo) e
dinamica di oggetti aventi Relazionabile come supertipo */

public class CollezioneConRelazione{

Vector collezione; // Rappresenta la collezione

/** COSTRUTTORE:
EFFECTS: Costruisce un nuovo oggetto di tipo CollezioneConRelazione
@param: void
@return: Il riferimento ad un oggetto di tipo CollezioneConRelazione */

public CollezioneConRelazione(){
collezione = new Vector(); // Crea la collezione assegnando a collezione il riferimento ad un vector vuoto
}

/** METODO INSERT():
EFFECTS: Se il Vector è vuoto inserisce un qualasiasi oggetto Relazionabile nella collezione, se ci sono già
altri oggetti inserisce l'oggetto referenziato dal paramentro dentro la collezione solamente se esso è
omogeneo con gli altri elementi della collezione, altrimenti solleva un'eccezione
@param: Un oggetto di tipo Relazionabile
@return: void */

public void insert(Relazionabile r){

int dimensione = collezione.size(); // Contiene la dimensione della collezione

if(dimensione == 0) // Se la collezione è vuota
collezione.addElement(r); // Il metodo aggiunge un qualsiasi Relazionabile alla collezione


else{ // Se invece la collezione non è vuota bisogna controllare che il parametro sia omogeneo con gli altri elementi
if(collezione.elementAt(0).getClass().isInstance(r))// Se il tipo del primo elemento è lo stesso del parametro r
collezione.addElement(r); // allora aggiunge l'elemento in coda alla colleazione
else throw new ElementoNonValidoException(); // Altrimenti solleva un'eccezione
}
}

/** METODO READ():
EFFECTS: Il metodo read() in base al parametro di input param opera nel seguente modo:
1) Se la collezione contiene elementi in relazione con il parametro, l'operatore calcola un iteratore
che enumera tutti gli elementi della collezione che sono in relazione con il parametro.
2) Qualora la collezione non contenga elementi in relazione con il parametro, l'operatore calcola il
primo elemento della collezione
@param: Il riferimento ad un oggetto di tipo Relazionabile
@return: Un oggetto di tipo MioIteratore che rappresenta l'iteratore richiesto dalle specifiche
@throw: Un'eccezione che eventualmente contenga il primo valore contenuto nella collezione */


}


Ora però mi impicco totalmente con il metodo read()...sò che bisogna fare + o - così (mi è stato detto):

Realizzare un particolare iteratore che prende come parametro un oggetto di tipo Relazionabile, l'iteratore restituisce tutti gli oggetti della collezione in relazione con tale parametro (se esistono), se invece non esiste nessun oggetto in relazione con il parametro SOLLEVA UN'ECCEZIONE CHE CONTIENE AL SUO INTERNO IL PRIMO ELEMENTO DELLA COLLEZIONE.

Io però non ho la minima idea di come si faccia un iteratore che accetti un parametro...mi potete dare una mano?

Grazie mille

banryu79
09-07-2009, 10:38
Io però non ho la minima idea di come si faccia un iteratore che accetti un parametro...mi potete dare una mano?

Ma... non basta che la classe Iteratore abbia come unico costruttore un costruttore che ha come parametro un Relazionabile?
tipo:

public class Iteratore
{
public Iteratore(Relazionabile r)
{
//...
}
}


Poi oggetti di questa classe vengono istanziati solo dal metodo read della CollezioneRelazionabile (o come diavolo si chiama :))

Rintrah84
09-07-2009, 10:43
Ma... non basta che la classe Iteratore abbia come unico costruttore un costruttore che ha come parametro un Relazionabile?
tipo:

public class Iteratore
{
public Iteratore(Relazionabile r)
{
//...
}
}


Poi oggetti di questa classe vengono istanziati solo dal metodo read della CollezioneRelazionabile (o come diavolo si chiama :))

Credo che sia qualcosa del genre...infatti stavo provando a farlo...però sono una mezza sega...spe tra un po' ti posto la mia idea e mi dici se può andare...

Rintrah84
09-07-2009, 11:47
mmm...ok...ho fatto come mi è venuto in mente...ma temo sia un po' un delirio e mi da anche qualche problemuccio in fase di compilazione...

Non riscrivo tutta la classe se no sarebbe lunghissimo.

Nella classe CollezioneConRelazione ho aggiunto una classe interna chiamata MioIteratore che implementa Iterator e che contiene al proprio interno 4 metodi:

1) Il costruttore dell'iteratore: se nella collezione è presente un oggetto relazionabile con il parametro r che riceve, fà partire da là l'iterazione; altrimenti solleva un'eccezione che contiene il riferimento al primo elemento della collezione.

2) next(): restituisce l'elemento corrente della collezione

3) hasNext(): Restituisce TRUE se nella collezione sono presenti altri elementi relazionabili con il parametro r o FALSE se non ci sono

4) remove(): Rimuove dall'iteratore l'elemento corrente (non dalla collezione), spostando l'indice all'eventuale altro oggetto in relazione con r presente nella collezione (se presente, altrimenti termina l'iterazione)

mmm sò che gli iteratori si possono fare anche in altri modi ma alla proff piacciono solo con questi 4 metodi precisi...

Poi ho creato un metodo enumera fuori dalla classe interna che semplicemente crea il mio iteratore e lo restituisce (per mascherarlo).

E poi ho creato il metodo read() che prende un relazionabile come parametro, prova a creare e a restituire l'iteratore specifico. Se nella collezione è presente almeno un elemento in relazione con il parametro r viene creato l'iteratore e restituito dal metodo read; Se invece nella collezione non è presente nessun oggetto in relazione con il parametro r, il metodo read cattura l'eccezione che contiene il riferimento al primo oggetto della collezione e la gestisce rimandandola al chiamante:

Il codice iper commentato del mio impiccio è questo:


/** METODO READ():
EFFECTS: Il metodo read() in base al parametro di input param opera nel seguente modo:
1) Se la collezione contiene elementi in relazione con il parametro, l'operatore calcola un iteratore
che enumera tutti gli elementi della collezione che sono in relazione con il parametro.
2) Qualora la collezione non contenga elementi in relazione con il parametro, l'operatore calcola il
primo elemento della collezione
@param: Il riferimento ad un oggetto di tipo Relazionabile
@return: Un oggetto di tipo MioIteratore che rappresenta l'iteratore richiesto dalle specifiche
@throw: Un'eccezione che eventualmente contenga il primo valore contenuto nella collezione */

public MioIteratore read(Relazionabile param){

Iterator it; // Dichiaro una variabile di tipo Iterator

try{ // Prova a costruire l'iteratore invocando il metodo enumera sulla collezione
it = collezione.enumera();
}catch(OggettiNonRelazionabiliException e){ // Cattura l'eventuale eccezione OggettiNonRelazionabiliException
/* E la gestisce rinviandola al chiamante che così riceve un'eccezione che contiene il riferimento al primo
oggetto della collezione */
throw new ggettiNonRelazionabiliException(collezione.elementAt(0));
}

return it;

}


private class MioIteratore implements Iterator{ // E' la classe interna che implementa l'interfaccia Iterator

private int dove; // Variabile che indica dove ci si trova all'interno della collezione durante l'iterazione
private int next; // Contiene l'indice del prossimo elemento della collezione relazionabile con il parametro


/* Costruttore del generatore, riceve come parametro un oggetto reazionabile e costruisce l'iteratore partendo
dal primo oggetto della collezione che è in relazione con il parametro (se esiste); Altrimenti se non esiste
solleva un'eccezione che contiene il riferimento al primo elemento della collezione */

public MioIteratore(Relazionabile r){

int i; // Variabile contatore per scorrere la collezione
boolean isFirst = false;

/* Scorre tutta la collezione finchè non raggiunge la fine oppure non trova un oggetto relazionabile con il
parametro */
for(i=0; i<collezione.size() && !isFirst; i++){

/* Se l'elemento corrente della collezione è relazionabile con il parametro mette dentro dove la sua
posizione e setta a true la variabile isFirst per terminare il ciclo */
if(collezione.elementAt(i).isInRelation(r)){
dove = i; // Mette la posizione del primo elemento in relazione dentro dove
isFirst = true; // Setta a true la variabile isFirst così da uscire dal ciclo
}
}

/* Se alla fine del ciclo isFirst è ancora false significa che la collezione è stata interamente scandita
senz che sia stato trovato nessun oggetto in relazione con il paramentro per cui viene sollevata
un'eccezione che contiene il riferimento al primo oggetto della collezione */
if(isFirst = false) throw new OggettiNonRelazionabiliException(collezione.elementAt(0));
}

/* Il metodo next() ritorna l'elemento corrente della collezione (che è in relazione con il parametro) */

public Object next(){
return collezione.elementAt(dove);
}

/* Il metodo hasNext() risponde true se l'oggetto nella collezione alla posizione indicata dalla variabile dove
non è l'ultimo oggetto della collezione ad essere in relazione con il paramentro r */

public boolean hasNext(Relazionabile r){

/* Variabile per scorrere la collezione alla ricerca del prossimo oggetto relazionabile con il paramentro r,
viene inizializzata a dove pechè deve vedere se dopo l'elemento corrente ci stà un altro elemento
relazionabile nella collezione */
int i = dove;

boolean altroRelazionabile = false;

/* Scorre tutta la collezione e termina quando non ci sono più elementi nella collezione o quando è stato
trovato il prossimo elemento della collezione che è in relazione con il parametro r */
while(i<collezione.size && !altroRelazionabile){

/* Se l'elemento corrente della collezione è relazionabile con il parametro m setta a true la variabile
altroRelazionabile per terminare il ciclo e mette dentro next la posizione del prossimo elemento
relazionabile con il parametro */
if(collezione.elementAt(i).isInRelation(r)){
next = i; // Setta next con il valore della posizione corrente
altroRelazionabile = true; // Setta a TRUE altroRelazionsabile per terminare la ricerca
}
}

/* Ritorna altroRelazionabile che indica al chiamante se nella collezione è presente o meno un altro oggetto
che è in relazione con il parametro r */
return altroRelazionabile;
}

/* Il metodo remove() rimuove l'elemento dall'iteratore (non dalla collezione) spostando dove al successivo
elemento della collezione che è in relazione con il parametro r */

public void remove(){
dove = next; // Setta dove a next calcolato precedentemente mediante hasNext()
}

}

/* Maschero l'implementazione di MioIterator usando un metodo enumera esterno alla classe interna */
public Iterator enumera(Relazionabile r){
return new MioIteratore(Relazionabile r);
}


Come logica cipuò stare?
Come mai mi dà questo errore n fase di compilazione?


C:\Programmi\Crimson Editor\template\esercizi\esami\08-06-2009>javac CollezioneConRelazione.java
CollezioneConRelazione.java:148: ')' expected
return new MioIteratore(Relazionabile r);
^
CollezioneConRelazione.java:148: not a statement
return new MioIteratore(Relazionabile r);
^
CollezioneConRelazione.java:148: ';' expected
return new MioIteratore(Relazionabile r);
^
3 errors


Tnx

banryu79
09-07-2009, 11:57
Come logica cipuò stare?
Come mai mi dà questo errore n fase di compilazione?

Perchè forse volevi scrivere:

return new MioIteratore(r);

Per quanto riguarda la logica del funzionamento che hai spiegato posso solo darti la mia opinione, che si basa sul fatto che "va bene tutto ciò che funziona".
Non ho un backgroud di studi rigorosi/università circa la programmazione percui potrei vedere le cose in modo molto diverso da come le valuta uno studioso o un professore.
Funziona? Allora direi che va bene (almeno è un punto da cui partire) :D

Rintrah84
09-07-2009, 12:04
Perchè forse volevi scrivere:

return new MioIteratore(r);

Per quanto riguarda la logica del funzionamento che hai spiegato posso solo darti la mia opinione, che si basa sul fatto che "va bene tutto ciò che funziona".
Non ho un backgroud di studi rigorosi/università circa la programmazione percui potrei vedere le cose in modo molto diverso da come le valuta uno studioso o un professore.
Funziona? Allora direi che va bene (almeno è un punto da cui partire) :D

funziona non ho ancora provato(anche perchè dava errorei in compilazione)...ed essendo un esame su carta il fatto che funzioni è alquanto relativo :D
Volevo solo sapere se secondo te come logica ci può stare (a prescindere dal rigore di un proff...magari non mi darebbe tutti i punti ma se proprio non ho scritto cappellate abberranti non mi darebbe comunque 0 punti)

banryu79
09-07-2009, 12:21
Beh, come logica ci sta, secondo me ;)

Rintrah84
09-07-2009, 14:37
ti ringrazio...speriamo bene...già una volta mi ci ha bocciato perchè avevo cannato in pieno questo iteratore...poi ci sono un altro paio di esercizzi in questo compito...ora li vedo poi semmai posto qualche altro dubbio :cry:

Tnx

banryu79
09-07-2009, 14:39
ti ringrazio...speriamo bene...già una volta mi ci ha bocciato perchè avevo cannato in pieno questo iteratore...poi ci sono un altro paio di esercizzi in questo compito...ora li vedo poi semmai posto qualche altro dubbio :cry:
Tnx
E ti ha spiegato/hai capito quale era l'errore/gli errori?
Solo così puoi essere sicuro di non ripeterli.

Rintrah84
09-07-2009, 15:14
E ti ha spiegato/hai capito quale era l'errore/gli errori?
Solo così puoi essere sicuro di non ripeterli.

Sostanzialmente non avvo fatto quell'iteratore mandando a donnine allegre più di mezzo compito...

banryu79
09-07-2009, 15:34
Ah, e beh! :D
Allora già il fatto di averne scritto uno che funziona è un grande passo avanti :sofico:

Rintrah84
09-07-2009, 15:40
Ah, e beh! :D
Allora già il fatto di averne scritto uno che funziona è un grande passo avanti :sofico:

che funziona ancora non lo sò (devo ancora testarlo)...che ha una sua logica già è qualcosa eheehhe :D

Rintrah84
09-07-2009, 16:52
Ok...altro problema (scusa se rompo ancora)...

c'è un altro punto del compito che dice:


Problema 3: Si richiede l’implementazione in Java di un metodo modifica di tipo void di seguito descritto:

· I parametri del metodo sono un oggetto di tipo CollezioneConRelazione e due oggetti ogg1 e ogg2

· Il metodo verifica se la collezione contiene elementi in relazione con ogg1 e:
o in caso affermativo, rimuove dalla collezione tutti gli elementi in relazione con ogg1;
o altrimenti, se il primo elemento della collezione è in relazione con ogg2, rimuove dalla collezione il suo primo elemento e vi inserisce ogg2.


Bene...l'ho fatto ma sicuramente è pieno zeppo di errori.

L'idea è questa: Il metodo modifica() è contenuto in un'altra classe che ho chiamato Utility.
Riceve come parametri di input ogg1 ed ogg2 di tipo Relazionabile ed un altro oggetto chiamato collezione di tipo CollezioneConRelazione.

Dichiaro un iteratore e provo a costruirlo mediante il metodo enumera() della classe CollezioneConRelazione passandogli l'oggetto ogg1.

Se viene sollevata l'eccezione OggettiNonRelazionabiliException allora significa che nella collezione non c'è nessun oggetto che è in relazione con il parametro ogg1, l'eccezione allora viene gestita controllando se ogg2 è in relazione con il primo elemento della collezione: se lo è ogg2 viene sostituito al primo elemento della collezione, altrimenti non succede nulla.

Se l'eccezione non viene sollevata allora vuol dire che almeno un elemento della collezione è in relazione con ogg1...allora devo usare l'iteratore per eliminare dalla collezione tutti gli elementi restituiti dall'iteratore (problemaccio)
Come logica può andare?
Il mio codice sbagliato è questo:


import java.util.*;

/** OVERVIEW: Si tratta di una classe contenitore di metodi utili per la gestione di oggetti di tipo
CollezioneConRelazione */

public class Utility{

/** EFFECTS: Riceve in ingresso due oggetti di tipo Relazonabile ogg1 ed ogg2 ed un oggetto di tipo
CollezioneConRelazione. Il metodo verificare se la collezione contiene oggetti in relazione con ogg1 ed in
caso affermativo rimuove dalla collezione tutti gli elementi in relazione con ogg1; Altrimenti, se il primo
elemento della collezione è in relazione con ogg2 allora rimuove il primo elemento e lo sostituisce con
ogg2
@param: ogg1 di tipo Relazionabile
@param: ogg2 di tipo Relazionabile
@param: collezione di tipo CollezioneConRelazione
@return: void */

public void modifica(Relazionabile ogg1, Relazionabile ogg2, CollezioneConRelazione collezione){

Iterator it; // Dichiaro una variabile di tipo iteratore

try{ // Prova a costruire l'iteratore invocando il metodo enumera sulla collezione
it = collezione.enumera(ogg1); // Crea il corretto iteratore per il parametro collezione

/* Finchè nella collezione ci sono ancora elementi su cui iterare (elementi in relazione con ogg1) */
while(it.hasNext()){
collezione.remove(it.next()); // Rimuove dalla collezione l'elemento corrente in relazione con il parametro ogg1
/* Passa al successivo elemento rimuovendo quello corrente dall'iteratore (non dalla collezione) */
it.remove();
}
}catch(OggettiNonRelazionabiliException e){ // Cattura l'eventuale eccezione OggettiNonRelazionabiliException
/* E la gestisce controllando se il primo elemento della collezione è in relazione con ogg2 */
if(collezione.elementAt(0).isInRelation(ogg2))
insertElementAt(ogg2, 0); // Sostituisce l'elemento in prima posizione con ogg2
} // L'eventuale eccezione ricevuta è stata gestita

}
}


Qualche ideuzza su come sistemarlo? (Mi stò sentendo stupido :cry: )

Grazie