PDA

View Full Version : [Java] Esercizio d'esame sulle interface


e-commerce84
26-05-2009, 10:13
Ciao,
questa è la prima parte di un vecchio compito d'esame....mi potete dire seè impostato correttamente?

Il testo dice:

Si consideri un metodo generaElementoACaso che prende in input una collezione generica di oggetti, ne estrae un iteratore, calcola e restituisce un elemento a caso della collezione.

Si richiede l'implementazione in linguaggio Java del metodo generaElementoACaso nonchè il progetto e l'implementazione in Java di tutti i tipi astratti ad esso necessari. Si utilizzi a tale scopo il metodo di istanza nextInt(), di tipo int, della classe Random.

Praticame io l'ho pensato così:

Mi definisco un'interface chiamata CollConIteratore che mi rappresenta genericissime collezioni di oggetti che hanno in comune una sola cosa: avere definito un iteratore.

Poi definisco una classe Utility che conterrà il metodo generaElementoACaso che mi si chiede di implementare sul testo dell'esercizio. Tale metodo prenderà come parametro il riferimento ad un oggetto CollConIteratore (quindi a qualsiasi oggetto istanza di una classe che implementa l'interface precedentemente definita) e restituirà al chiamante il riferimento ad un Object (ad un Object perchè sarà per forza di cose il riferimento ad un oggetto istanza di una classe che implementa l'interface CollConIteratore)

Quindi in codice qualcosa del genere:

Intereface CollConIteratore:

public interface CollConIteratore{
Iterator enumera();
}


Classe Utility contenente il solo metodo generaElementoACaso:

public class Utility{

/** REQUIRES: C != 0
EFFECTS: Restituisce un elemento casuale presente nella collezione C
@param: un oggetto di tipo CollConIteratore
@retur: il riferimento ad un Object */
public static Object get ElementoACaso(CollConIteratore c){

Random r = new Random m(): // Crea un oggetto random
Iterator it = c.enumera(): // Crea il corretto iteratore per la collezione c
int quale = r.nextInt(); // Genera un intero casuale partendo da un oggetto random
int i = 0;
int quanti = 0;

while(i < quale){ // Finchè il contatore i è minore del numero casuale quale precedentemente generato
it.remove; // Rimuovi l'elemento dall'iteratore (non dalla collezione, passa soloal prossimo elemento dell'iteratore)
i++; // Incrementa i di 1
}

/* Ritorna al chiamante il prossimo elemento nella collezione che corrisponde all'elemento nella posizione quale
generata in maniera casuale */
return it.next();
}
}


Ci può stare come impostazione?

mmm tra l'altro ho vari problemi...qualche giorno fa mi sono beccato un virus devastante sul mio portatile ed ho dovuto usare avira (un antivirus bootabile) che mi ha trovato e bloccato varie porcate dentro Java...ed ora mi stà dando qualche problema a compilare questa cosa (però non sò se c'entra nulla)...ad esempio mi dà:

C:\Programmi\Crimson Editor\template\esercizi\esami\07-02-07>javac CollConIteratore.java
CollConIteratore.java:2: cannot find symbol
symbol : class Iterator
location: interface CollConIteratore
Iterator enumera();
^
1 error

Può dipendere da questi casini o ho sbagliato qualcosa io?
Altra cosa...prima quando premevo il tasto TAB nel prompt di msdos mi completava le parole già iniziate...ora no...booo

Tnx

banryu79
26-05-2009, 12:25
C:\Programmi\Crimson Editor\template\esercizi\esami\07-02-07>javac CollConIteratore.java
CollConIteratore.java:2: cannot find symbol
symbol : class Iterator
location: interface CollConIteratore
Iterator enumera();
^
1 error

Il compilatore javac non trova il simbolo definito come "Iterator".
Nel file .java che continene la definizione di "CollConIteratore", il simbolo "Iterator" non è definito: se è una classe o interfaccia devi definirla.
Se la sua definizione esiste ma si trova in un altro package, devi importarla mediante l'istruzione di import prima di poterla usare.

Supponiamo che tu voglia usare la dafinizione dell'interfaccia Iterator inclusa nel JDK e locata nel package java.util: in questo caso sarebbe sufficiente porre prima della definizione di CollConIteratore l'import, così:

import java.util.Iterator;

public interface CollConIteratore{
Iterator enumera();
}





Tnx

Prg.

e-commerce84
26-05-2009, 20:01
Ok ho capito...si intendevo proprio utilizzare la definizione di Iterator presente nella JDK infatti mi sono accorto che su un appunto anche la proff faceva quell'import :-)

La logica dell'esercizio cmq andava bene?

Poi ci sarebbe il secondo punto di questo compito d'esame (che si basa sul precedente) e che dice:

Problema 2. Si richiede il progetto e l’implementazione in linguaggio Java dei due tipi di dato seguenti in
modo tale che essi possano essere parametri del metodo generaElementoACaso:
1) una collezione di numeri interi positivi (ad esempio, i numeri di serie dei biglietti venduti di una
lotteria)
2) un rettangolo, in cui l’iteratore enumeri i quattro vertici. Si utilizzi allo scopo la classe di cui si
forniscono le seguenti specifiche:


public class Rettangolo {
.... /* variabili di istanza */
/* costruisce un oggetto di tipo Rettangolo date le coordinate
(xinf, yinf) del suo vertice inferiore sinistro e le coordinate
(xsup, ysup) del suo vertice superiore destro */
public Rettangolo(double xinf, double yinf, double xsup, double ysup) { }
/** restituisce il vertice inferiore sinistro dell’oggetto
ricevente */
public Punto getBottomLeftCorner() { }
/** restituisce il vertice superiore sinistro dell’oggetto
ricevente */
public Punto getTopLeftCorner() { }
/** restituisce il vertice superiore destro dell’oggetto
ricevente */
public Punto getTopRightCorner() { }
/** restituisce il vertice inferiore destro dell’oggetto
ricevente */
public Punto getBottomRightCorner() { }
}


MIA SOLUZIONE:
Vabbè per il primo punto credo sia facilissimo e credo basti creare una classe CollIntConIteratore che rappresenta una collezione di interi, che implementa l'interfaccia precedentemente generata e che quindi implementi anche il metodo enumera per l'iteratore, quindi qualcosa del genere:


import java.util.Iterator;

private class CollIntConIteratore implements CollConIteratore{

private int[] A; // La collezione è definita tramite un array di interi

/** REQUIRES: B != 0
EFFECTS: Crea un nuovo oggetto di tipo CollIntConIteratore
@param: Il riferimento ad un array di int
@return: Il riferimento ad un nuovo oggetto di tipo CollIntConIteratore */
public CollIntConIteratore(int[] B){
int i; // Variabile contatore
A = new int [B.length]; // Costruisci un nuovo array avente la stessa lunghezza del parametro B

for(i=0; i<A.length; i++) // Copia in A tutti gli elementi presenti in B
A[i] = B[i];
}

private class MioIteratore implements Iterator{ // E' una CLASSE INTERNA che implementa l'interface Iterator
private int k; // Variabile per iterare sulla collezione

public MioIteratore(){ // Costruttore del generatore
k = 0; // Quando viene costruito parte dal primo elemento della collezione in posizione 0
}

public Object next(){ // Restitituisce l'elemento in posizione k della collezione incartato in un Integer
return new Integer(A[k]);
}

public boolean hasNext(){ // Dice se c'è un altro elemento nella collezione
return k<A.length;
}

public void remove(){ // Rimuove l'elemento dall'iteratore (non dalla collezione) passando al prossimo elemento
k++;
}
}

public Iterator enumera(){ // Maschero l'implementazione di MioIterator usando un metodo enumera
return new MioIteratore();
}
}


Invece il secondo punto mi ha creato un po' più di difficoltà e non sono sicuro di aver fatto tutto bene...

Mi viene data una classe Rettangolo prefatta (quindi io avrei il bytecode)....devo incartare tale classe dentro una classe RettangoloConIteratore che a sua volta estende Rettangolo ed implementa l'interfacia CollezioneConIteratore (quindi è un caso di ereditarietà multipla).

Per costruire un nuovo oggetto di RettangoloConIteratore uso semplicemente il costruttore della superclasse Rettangolo passandogli i due vertici richiesti.

Il mio cruccio è su come ho implementato l'iteratore per questo tipo di dati...nel senso che non sono sicuro su quanto possa essere lecito lanciare quell'eccezione unchecked qualora si provasse ad iterare su un angolo inesistente....


import java.util.Iterator;

public class extends Rettangolo implements CollezioneConIteratore{ // Ereditarietà multipla

/** REQUIRES: Il rettangolo non deve essere degenere, cioè i punti forniti per costruirlo devono essere diversi
e coerenti con le specifiche richieste (uno il vertice inferiore sinistro e l'altro il vertice superiore
destro).
EFFECTS: Crea un nuovo oggetto di tipo RettangoloConIteratore
@param: Le coordinate cartesiane del vertice inferiore sinistro e del vertice superiore destro: Xinf, Yinf, Xsup Ysup
@return: Il riferimento ad un nuovo oggetto di tipo RettangoloConIteratore */

public RettangoloConIteratore(double Xinf, double Yinf, double Xsup, double Ysup){
super(Xinf, Yinf, Xsup, Ysup); // Invoca il costruttore della superclasse Rettangolo passandogli i parametri ricevuti
}

private class MioIteratore implements Iterator{ // E' una CLASSE INTERNA che implementa l'interface Iterator

private int i; // Variabile per iterare sulla collezione

public MioIteratore(){ // Costruttore del generatore
i = 1; // Quando viene costruito parte dal primo elemento della collezione (vertie inferiore sinistro)

}

public Punto next(){ // Restitituisce l'elemento in posizione i della collezione (l'i-esimo vertice)

if(i==1)
return super.getBottomLeftCorner();

else if(i==2)
return super.getTopLeftCorner();

else if(i==3)
return super.getTopRightCorner();

else if(i==4)
return super.getBottomRightCorner();

else throw IndiceNonValidoExceptio()
}

public void remove(){
i ++; // Non elimina l'oggetto dalla collezione ma lo rimuove solo dall'iteratore
}

public boolean hasNext(){ // Dice se c'è un altro elemento nella collezione
return i<4; // Se i è minore di 4 c'è ancora almeno un vertice da restituire
}
}

public Iterator enumera(){ // Metodo che restituisce il riferimento ad un oggetto che implementa Iterator
return new MioIteratore(); // Ritorna il riferimento ad un oggetto di tipo MioIteratore appena creato
}
}


Che ne dici?

Sinceramente...lo avrei passato questo esame secondo te?

Tnx

banryu79
27-05-2009, 11:30
Ok ho capito...si intendevo proprio utilizzare la definizione di Iterator presente nella JDK infatti mi sono accorto che su un appunto anche la proff faceva quell'import :-)

La logica dell'esercizio cmq andava bene?

La logica di per se sì.
Comunque se puoi utilizzare il JDK come base d'appoggio per non dover "reinventare la ruota" ogni volta, e lo puoi fare dato che hai importato java.util.Iterator, perchè non sfrutti la definizione dell'interfaccia java.util.Collection (http://java.sun.com/javase/6/docs/api/java/util/Collection.html) lì definita?

Leggendo il testo dell'esercizio:

Si consideri un metodo generaElementoACaso che prende in input una collezione generica di oggetti, ne estrae un iteratore, calcola e restituisce un elemento a caso della collezione.

Si richiede l'implementazione in linguaggio Java del metodo generaElementoACaso nonchè il progetto e l'implementazione in Java di tutti i tipi astratti ad esso necessari. Si utilizzi a tale scopo il metodo di istanza nextInt(), di tipo int, della classe Random.

puoi creare una tua classe che implementa l'interfaccia java.util.Collection e la realizza dotandola di (per esempio) un array di Object, e implementando tutti i metodi astratti.
Tra questi c'è il metodo 'iterator' che, appunto, restituisce un java.util.Iterator sulla collezione.

In questo modo avresti implementato anche la collezione, che viene richiesta come parametro di input del metodo 'generaElementoACaso', soddisfando uno dei requisiti del richiesti dall'esercizio:

...
Si richiede l'implementazione in linguaggio Java del metodo generaElementoACaso nonchè il progetto e l'implementazione in Java di tutti i tipi astratti ad esso necessari. Si utilizzi a tale scopo il metodo di istanza nextInt(), di tipo int, della classe Random.





Tnx

Prg.