PDA

View Full Version : [Java] devo creare un multiset...


leox@mitoalfaromeo
29-10-2006, 13:33
Ciao:D
Sto convertendo un generatore di istanze pseudocasuali da c++ a java (per i noti problemi di ripetibilità del primo linguaggio)
ho quasi finito ma mi manca un ultimo step...

In c++ avevo usato un multiset per inserire quando mi serviva in una lista una serie di oggetti di tipo Event da me creato. Avevo ridefinito l'operatore < su questi oggetti in modo che confrontasse il campo Event.time. Nella pratica questa bella costruzione mi permetteva di inserire in lista gli eventi man mano che li generavo e di avere alla fine una lista cronologicamente ordinata...

Si può fare qualcosa del genere in java?? ho definito sulla classe Event il metodo isBefore() per l'ordinamento ma ora non saprei bene come fare... ho visto sulla doc del sito java che la classe multiset esiste ma non si capisce come costruirne un oggetto nè come specificare il metodo di ordinamento...

(non ditemi che devo fare un vettore e poi ordinarlo...)

PGI-Bis
29-10-2006, 13:49
Credo che tu possa usare un TreeSet. La cosa più simile a quanto hai fatto in C++ è dichiarare il tuo Event concretizzazione di Comparable<Event>. A questo punto dovrai dotare Event di un metodo:

public int compareTo(Event that) {
restituisce
zero se this vale quanto that
un numero minore di zero se this è minore di that
un numero maggiore di zero se this è maggiore di that
}

Probabilmente farai il confronto dell'equivalente del campo time. Comunque sia, una volta che hai fatto diventare Event un Comparable, il metodo compareTo diventa la definizione dell'ordine naturale degli oggetti Event. E hai finito. TreeSet è uno dei tanti attrezzi che sanno cosa fare con elementi naturalmente ordinabili. Sa anche cosa fare con elementi non direttamente ordinabili ma è un altro paio di maniche.

TreeSet<Event> eventSet = new TreeSet<Event>();

Quando aggiungi un Event ad eventSet TreeSet si occupera di fare in modo che lo scorrimento dell'insieme presenti quel dato evento in una posizione consona all'ordine naturale degli Event.

Il tutto a meno che io non abbia capito una mazza, nel qual caso scomparirò con una pernacchia e una piroetta :D.

mad_hhatter
29-10-2006, 14:57
nella documentazione ufficiale di java leggiti le info relative all'interfaccia Comparable che deve essere implementata dalla tua classe per poter definire un ordinamento naturale tra le istanze di tale classe. In tal modo potrai usare l'operatore > o < perchè il compilatore userà automaticamente il metodo compareTo (come detto da PGI-bis) da te creato perchè richiesto dall'interfaccia comparable

PGI-Bis
29-10-2006, 15:20
A meno che non abbiano introdotto una nuova regola per il linguaggio, se PGI-BIS avesse veramente detto "potrai usare l'operatore > o < perchè il compilatore userà automaticamente il metodo compareTo" allora PGI-Bis dovrebbe fare harakiri. Con la tastiera, perchè così fa più male.

mad_hhatter
29-10-2006, 15:28
si scusate, ho detto una vaccata

cmq a scanso di equivoci citavo PGI-bis in merito al metodo compareTo, e basta

leox@mitoalfaromeo
29-10-2006, 16:06
perdonatemi se dico vaccate, in fondo sono un povero ingegnere gestionale..

il primo step che dovevo fare, se ho capito bene, era quello di dichiarare la classe Event come un'estensione di Comparable... giusto?
quindi ho dichiarato:
public class Event implements Comparable
ma mi ritorna un errore (che nei giorni scorsi già mi ha rotto le palle con Queue fino ad obbligarmi a rinunciare al suo uso...)
jgenerator.Event is not abstract and does not override abstract method compareTo(java.lang.Object) in java.lang.Comparable
:confused: :confused: :confused: :confused:

mad_hhatter
29-10-2006, 16:09
credo ti stia dicendo che hai dichiarato che la tua classe avrebbe implementatao l'interfaccia comparable, ma per implementare tale interfaccia devi definire il metodo compareTo

leox@mitoalfaromeo
29-10-2006, 16:27
purtroppo anche definendo il metodo compareTo non cambia nulla...
EDIT:
invece no!!!
bisognava dichiararlo così:
public class Event implements Comparable<Event>

leox@mitoalfaromeo
29-10-2006, 16:36
ma poi l'implementazione di compareTo come si fa?!?!
ho provato così:
public int compareTo(Event e) {
return this.time_when.compareTo(e.time_when);
}

andrà bene??

mad_hhatter
29-10-2006, 16:38
come avrai capito il metodo richiesto da un'interfaccia ha un descrittore dello scope del metodo, un tipo di dato da ritornare e una lista di argomenti che DEVONO essere rispettati e che sono definiti nell'interfaccia che implementi

mad_hhatter
29-10-2006, 16:42
ma poi l'implementazione di compareTo come si fa?!?!
ho provato così:
public int compareTo(Event e) {
return this.time_when.compareTo(e.time_when);
}

andrà bene??


allora, in soldoni il metodo compareTo deve ritornare un intero >0 se this è concettualmente maggiore dell'argomento del metodo, <0 se this è concettualmente minore di bla bla e =0 se le due entità sono concettualmenti uguali. in particolare compareTo deve tornare 0 se e solo se il metodo equals() dell'interfaccia comparable torna true. trovi questi dettami nella doc ufficiale dell'interfaccia comparable.

se il membro time_when ammette un metodo compareTo coretto, direi che quello che hai scritto va benissimo

leox@mitoalfaromeo
29-10-2006, 17:05
allora, in soldoni il metodo compareTo deve ritornare un intero >0 se this è concettualmente maggiore dell'argomento del metodo, <0 se this è concettualmente minore di bla bla e =0 se le due entità sono concettualmenti uguali. in particolare compareTo deve tornare 0 se e solo se il metodo equals() dell'interfaccia comparable torna true. trovi questi dettami nella doc ufficiale dell'interfaccia comparable.

se il membro time_when ammette un metodo compareTo coretto, direi che quello che hai scritto va benissimo
bè si.. time_when è fondamentalmente un intero quindi dovrebbe funzionare....
ora cmq ho un altro maledettissimo problema... devo stampare gli eventi nel TreeSet ma non capisco come fare... perchè il maledetto non ha un metodo che restituisce l'elemento i-esimo, ma semplicemente first() o last()...

mad_hhatter
29-10-2006, 17:10
http://java.sun.com/j2se/1.5.0/docs/api/java/util/TreeSet.html

guarda il metodo iterator()

per jdk 1.4.2 : http://java.sun.com/j2se/1.4.2/docs/api/java/util/TreeSet.html
stesso metodo

leox@mitoalfaromeo
29-10-2006, 17:56
http://java.sun.com/j2se/1.5.0/docs/api/java/util/TreeSet.html

guarda il metodo iterator()

per jdk 1.4.2 : http://java.sun.com/j2se/1.4.2/docs/api/java/util/TreeSet.html
stesso metodo
in realtà l'avevo visto... ma non capivo e tuttora non capisco come usarlo...

ho provvisoriamente risolto in questo modo:
Event[] outBuf= new Event[eventSet.size()];
eventSet.toArray(outBuf);
for(int i=0; i<outBuf.length; i++){
System.out.println(outBuf[i].toString());}


dove eventSet è il TreeSet... forse non è particolarmente elegante ma funziona:D

in particolare ho potuto verificare che l'ordinamento viene fatto correttamente in base al tempo!!

GRAZIE 1000 A TUTTI.. siete stati preziosissimi, vi citerò nei ringraziamenti della tesi:D:D

mad_hhatter
29-10-2006, 18:10
in bocca al lupo :)

lovaz
30-10-2006, 12:56
Dovrebbe funzionare anche così, non serve convertirlo in array:
for( Event e : eventSet )
System.out.println( e );

leox@mitoalfaromeo
30-10-2006, 17:47
Dovrebbe funzionare anche così, non serve convertirlo in array:
for( Event e : eventSet )
System.out.println( e );
semmai
for( Event e : eventSet )
System.out.println( e.toString() );

provo, poi vi dirò:D

mad_hhatter
30-10-2006, 22:10
quando fai print(e) il compilatore chiama automaticamente il corrispondente metodo toString()... stavolta sono sicuro (quasi :D )

leox@mitoalfaromeo
03-11-2006, 21:17
allora miei cari... oggi sono stato a fare 2 chiacchiere col prof e tra le altre cose ho risolto il problema dell'accesso agli elementi del treeSet...

la chiave era effettivamente il metodo iterator().
In particolare bisogna creare un oggetto di tipo Iterator che poi supporterà i metodi Next() che restituisce l'elemento successivo e HasNext() che è un booleano per trovare la fine del vettore..
è una cosa nuova di java 1.5.

quindi il mio ciclo di stampa sul treeSet è venuto così:

for(Iterator i=j.eventSet.iterator(); i.hasNext(); )
System.out.println(i.next());


e l'amico mad aveva ragione sul fatto che non è necessario chiamare toString() al momento della stampa perchè lo capisce da sè!

PGI-Bis
03-11-2006, 22:45
allora miei cari... oggi sono stato a fare 2 chiacchiere col prof e tra le altre cose ho risolto il problema dell'accesso agli elementi del treeSet...

la chiave era effettivamente il metodo iterator().
In particolare bisogna creare un oggetto di tipo Iterator che poi supporterà i metodi Next() che restituisce l'elemento successivo e HasNext() che è un booleano per trovare la fine del vettore..
è una cosa nuova di java 1.5.

Di al tuo professore che è ora che si aggiorni. Iterator c'è da Java 1.2 (praticamente da poco dopo che Noè scese dalla barca :D).

Quello che c'è in Java5 è Iterable che è uno dei mezzi che ti consente di usare il ciclo foreach proposto da Lovaz e che, a questo punto, suppongo che tu debba usare.

leox@mitoalfaromeo
03-11-2006, 23:22
Di al tuo professore che è ora che si aggiorni. Iterator c'è da Java 1.2 (praticamente da poco dopo che Noè scese dalla barca :D).

Quello che c'è in Java5 è Iterable che è uno dei mezzi che ti consente di usare il ciclo foreach proposto da Lovaz e che, a questo punto, suppongo che tu debba usare.
probabilmente ho fatto confusione io... mi sa che parlava di iterable...