Programmazione di base in Java · linguaggio di programmazione Java. Poi prosegue con lo sviluppo...

97
Programmazione di base in Java Paolo Bison Technical Report 12/00, LADSEB-CNR Padova, Italy, Novembre 2000. LADSEB-CNR Corso Stati Uniti 4 I-35127 Padova, Italy e-mail:[email protected] tel: 049 8295765 fax: 049 8295763

Transcript of Programmazione di base in Java · linguaggio di programmazione Java. Poi prosegue con lo sviluppo...

Programmazionedi basein Java

PaoloBison

TechnicalReport 12/00, LADSEB-CNRPadova, Italy , Novembre2000.

LADSEB-CNRCorsoStatiUniti 4

I-35127Padova,Italye-mail:[email protected]

tel: 0498295765fax: 0498295763

PrintedonOctober12,2001

SOMMARIO

Questorapporto inizia con unabreve introduzione alla programmazione ad oggetti ed unasinteticadescrizione dellinguaggiodi programmazioneJava. Poiprosegueconlo sviluppo di programmi in Javacherealizzanoalgoritmi basedell’informatica,spaziando da semplicie banaliprogrammi proceduralifino alla realizzazione di programmi basatisullaprogrammazioneadoggetti. Vengonoinoltreillustrati programmiricorsivi, di ricercaedordinamento,di gestionedi strutturedinamicheedi ingresso/uscita.Infinevengonopresentatii risultati in termini di tempidi calcoloperalcunisemplibenchmarks.Tutti i programmisonostati sviluppati ed eseguiti su unaworkstationSunutilizzandol’ambientedi sviluppoJDK(JavaDevelopmentKit).

ABSTRACT

In the first part of this report a short introduction to ObjectOrientedprogramming anda brief description of Javaprogramming languagearegiven.Thentheuseof this language is shown throughprograms,whichrealizesomebasicalgorithms,startingfrom simpleprogramsto complex full OO programs.Moreover, thereareprogramswhich dealswith the following points: recursive programming, searchandsort algorithms, dynamic structuresandinput/outputprogramming. At theend,theperfomanceof theJavarun-time systemareshown throughsimplebenchmarks.All programshasbeendevelopedandtestedona SunworkstationusingtheJavaDevelopmentKit (JDK).

INDICE

1 Programmazione ad oggetti 11.1 Oggetto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Messaggio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 Classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.4 Ereditarieta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.4.1 Ereditarietasingola . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.4.2 Ereditarietamultipla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Il linguaggio Java 52.1 Commento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Dichiarazione di variabile. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.3 Tipi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.4 Tipi base. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.5 Costanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.6 Classi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.6.1 Opzionipervariabili emetodi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.6.2 Variabili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.6.3 Metodi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.6.4 Creazionedi oggetti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.5 Interfacce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.6 Classiinterne(innerclasses). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.7 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.7 Conversioni di tipo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.7.1 Implicite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.7.2 Esplicita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.8 Espressioniedoperatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.8.1 Precedenzadegli operatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.8.2 Associativita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.8.3 Ordinedi valutazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.8.4 Operatori aritmetici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.8.5 Concatenazionedi stringhe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.8.6 Operatori di confrontoe logici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.8.7 Operatori sui bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.8.8 Operatori di assegnazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.9 Eccezioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.10 Istruzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3 Programmi procedurali. 173.1 Programmi banali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.2 Stampadegli argomenti. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.3 Programmi sullestringhe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.4 Calcolodel fattoriale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203.5 MassimoComunDivisoredi Euclide. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.6 Crivello di Erastotene. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.7 Divisioneesatta. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.8 Fattoriale“overloaded”. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4 Programmi orientati agli oggetti. 294.1 Numericomplessi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294.2 Calcolomatriciale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324.3 Quadratomagico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.4 Figuregeometriche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384.5 Ereditarietamultipla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

5 Programmi ricorsivi. 455.1 Fattoriale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455.2 Programmi sullestringhe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465.3 Anagrammi di unalista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.4 Torredi Hanoi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.5 Fai date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

6 Ricercaedordinamento 556.1 Ricercasuarray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556.2 Ordinamentodi array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566.3 Ordinamentodi arraygenerico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

7 Struttur edinamiche 637.1 Liste suinteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

7.1.1 Nododellalista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637.1.2 Lista FirstInFirstOut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637.1.3 Lista FirstInFirstOutottimizzata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647.1.4 Lista LastInFirstOut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

8 Files e Input/Output. 678.1 Gestionedeifile. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 678.2 Letturafile di tipo ASCII. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688.3 Letturamediante StreamTokenizer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698.4 Archiviazionein formatoZIP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

A Prestazioni 77

B Risorseal Ladseb 85B.1 Macintosh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85B.2 Sun450 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Bibliografia 87

Capitolo 1

Programmazionead oggetti

In questocapitoloverranno introdotti brevementei concettigenerali dellaprogrammazioneadoggettichesi ritrovanoin tutti queilinguaggicheadottano talemetodologia.

1.1 Oggetto

Nell’ambito dellaprogrammazione conil termineoggetto(object)si individuaun agentecomputazionale, ovverounagentechepuo eseguire delleelaborazioni,caratterizzato dadueelementi:

� unostatointernocherappresental’indi vidualita dell’oggettostessoe chevienedescrittodadellevariabili

� uninsiemedi metodichedefinisconole capacitaelaborativedell’oggetto,o in altreparole,le computazionichel’oggettopuooperare.Ognimetodorappresentaunasequenzadi istruzioni chel’oggettopuo eseguire.

Eseguendole istruzionicontenute neisuoimetodiunoggettopuo essenzialmente:

� modificareil proprio statointernocambiando i valori assegnatialle variabili chelo descrivono

� creare nuovi oggetti

� interagire conaltri oggetti, compresosestesso,attraversol’invio di messaggi

L’unica modalita di interazione cheesistetra oggettie quellaelencatanel terzopunto, scambiodi messaggi,percui unoggetto nonpuo modificarei valori dellevariabili chedescrivono lo statodi unaltrooggetto.

Gli unici elementi visibili di unoggettosonoi suoimetodichedefiniscono la suainterfacciao protocollo. Questo

� � � � � � ���� ���� �

��� � �� ��

����� !"#$%&'( )+*�,�-

)+*�,�.)/*0,21

Figura1.1: Rappresentazionedi unoggetto

modello inglobandoin unaunicaentita dati (variabili di stato)e programmi cheli manipolano(metodi)permettedimodularizzareedi nasconderei dettaglinonsignificativi (informationhiding).

1.2 Messaggio

Un messaggioe l’unita di informazionechevienescambiatatradueoggetti e rappresentala richiestadi esecuzionediunparticolaremetodo. E compostodaiseguentielementi:

2 1. Programmazione adoggetti.

� oggettodestinatarioe l’oggettochedeveeseguire il metodo acui si riferisceil messaggio

� nomedelmetodoe utilizzatoperidentificareil metodo chedeveessereeseguito

� eventuali parametrisonoriferimenti adaltri oggettichefornisconoulteriore informazione al metodo

3 4 5 6 7 8 9 :<; =?>@BAC

DEFGHIJKML/NBO

KMLPNBQ

3 4 5 6 7 8 RSUTPVXWZYM[ \

]0^_ `a bc

defghijklmnopq

KML/NBO

KML/NBQKML/N?r

sut vBw x wy{z w |

}P~��w |} �Z�

Figura1.2: Scambiodi unmessaggio

1.3 Classe

Col termineclassesi individuaun elemento chepermettedi descrivere le componentidi un particolareoggetto. Unaclassedefiniscele variabili edi metodidi un insiemedi oggetti. Tali oggettivengonocreatidinamicamenteevengonodetti istanzedi taleclasse.In uncertosensola classerappresentaunoggettoastratto.E possibiledefiniresiavariabilichemetodi di classe.Nel primocasotali variabili sonocondivisetra tutti gli oggetti cheappartengono alla classe,percui modifiche effettuatedaunoggetosullevariabili di classesonovistedatutti gli altri oggetti dellastessaclasse.

La classepuo esserevista comeun contenitore per la definizione delle variabili e per i metodiassociaticon glioggetti. Concettualmentequando un oggettovienecreatosi cercanellaclassela definizione dellevariabili perpotergenerarelo statoassociatoall’oggettoequando egli riceveunmessaggio,si cercanellaclassedi cui e istanzail metodoassociatoal nome cheharicevuto conil messaggio.

1.4 Ereditarieta

Definizione di unaclasse(subclass)in termini di altreclassi(superclass).Questoprocessodi ereditarieta e iterativopercui unasubclasspuo diventareasuavoltaunasuperclass.La classeeredita tuttele componenti(variabili emetodi)definitenellesuesuperclassi,mainoltrepuo:

� definirenuovevariabili e/ometodi

� ridefinirevariabili e/ometodipresentinellesuesuperclassi

In ogni sistemaOO esisteunaclassechee la madredi tutte le classi,ovveroil punto d’origine per l’ereditarieta.Taleclassenonhaavviamentenessunasuperclasse.In Java e la classeObject.

L’ereditarieta definisceunagerarchiadi classi,chepuo esserestrutturatasiaadalbero(ereditarieta singola)siaagrafo (ereditarietamultipla). Dal puntodi vistadellaprogramazione,questoconcettopermettedi strutturareil codicein manierataledafacilitareil suoriuso. Infatti il codicedefinitoadalti livelli gerarchici vienecondiviso datutte leclassichestannoal di sottoechelo ereditano. Le classial livello superioredefinisconocodicedi usogeneralementrele classichevengonovia via definiteai livelli sottostantilo specializzanoin funzionedegli oggetticherappresentano.

Inoltre la strutturaereditaria stabiliscegli ambiti di definizione per i vari elementi del linguaggio (ad esempiovariabili emetodi)e le modalitaperle loro associazioni.Ad esempio,seunoggettoriceveunmessaggioil cui codicenone presentenellaclassedell’oggettosi ricercanellesuperclassidi taleclasse,cosivia in maniera ricorsiva finche

1. Programmazione adoggetti. 3

nonsi trova talecodiceo vienegeneratoun errore. L’associazionetra unmessaggioedun metodo chelo implementapuo esserefattaal tempodellacompilazione,oppureall’atto dell’esecuzione.Nel primo casosi ottieneunprogrammapiu efficiente,macon la necessita di aver definitoprimatutte le classie i loro rapporti ereditari. Nel secondo, si hala possibilita di unaprogrammazione incrementale percui none necessariodefinirei vari elementisenonvengonoutilizzati all’esecuzione; d’altrapartesi haunsistemamenoeffciente perche il codicedaeseguire deveesserecercatodurante l’esecuzione.

1.4.1 Ereditarieta singola

Quando unaclassepuo averesolamenteunasuperclassee quindi ereditareattraversounasolaclasse,si ha il casodiereditarieta singola.

La relazione di ereditarieta vienerappresentatada un albero comein figura 1.3 chevisualizzale relazionipertre classicherappresentanopossibili elementi di una interfacciautenetgrafica: unafinestragenerica, unafinestradi dialogo edunafinestracontitolo. La classegenitrice,chein questocasocorrispondealla radicedell’albero, e laclasseFinestraSemplicei cui elementi(le variabili x,y,alt,larg edi metodidisegna,trasla)sonoereditatisiadallaclasseDialogosiadallaclasseFinestraTitolo. Nella classeDialogovengonodefinete duenuove variabili (mes,bottone) edun nuovo metodo (premi) mentresi ridefinisceil metododisegnaper tenercontodelladiversaimmaginegrafica.INmanierasimile per la classeFinestraTitolo cheridefiniscesempreil metodoDisegna, ma cheaggiunge la variabiletitolo.

��� ��������� �������P�������� �����������/� � ���

� � � ��� ���/��� ����� � �����

� � �������������� �����

� � � ��� ���/��� � ������������ �� U��������� ��<���M� ������� � � ���¡�

¢ � ���������£u¤�¥�¥�¦¨§�§�© ª

«/¬ ­M®°¯¨± ²�³°´

Figura1.3: Alberodi ereditarieta

1.4.2 Ereditarieta multipla

Seunaclassepuo ereditaredapiu classisi hal’ereditarietamultiplaedin questola relazione di discendenzatraclassie rappresentatadaungrafo.

Un esempiodi questotipo e mostratoin figura1.4. Si immagini chela classeBeatCount descrivadegli oggetticheconsentonodi misurareil tempoe si voglia costruiredegli orologi chevisualizzinol’ora. Si puo ottenerequestodefinindo dellesottoclassicheaggiungonoallaclasseBeatCount la rappresentazionegrafica.In questocasovi sonodueclassi:la classeAnaClock pergli orologi conqudranteanalogicoela classeDigiClock µ ¶P· µX¸ pergli orologi convisualizzazionedigitale. Perrappresentaredegli orologi cheabbianosia il quadranteanalogicochequellodigitale,sidefiniscela classeDiAnaClock ¹ º » ¹ ¼ cheraggruppale definizioni delledueclassidi visualizzazionein ununico elementoattraversoil meccanismodell’ereditarietamultipla. A questopunto si hanno a disposizionedegli oggeticonentrambele funzionalita.

Benchequestometodo siaconcettualmentesemplice,la suarealizzazionepraticapresentadelledifficoltadel tipo:

� ambiguita sui nomiquando le superclassihannometodie/o variabili con lo stessonome,l’uso di tale nomenella sottoclasseeambiguoperche nonsi saa qualeelementoassociarlo

� esecuzionedeimetodiil come ed in qualesequenzavengono eseguiti i metodi delle superclassiinfluenzail comportamento comp-lessivo delprogramma,adesempio,sottocertecondizioni epossibilechealcuni metodi possanoessereeseguitiduevolte.

4 1. Programmazione adoggetti.

½¿¾ÁÀ¿½ÃÂ

ÄÆÅÈÇ�ÄÆÉ

ÊÌËÆÍ�ÎPÏÑÐÓÒÔÎ

Õ ÔÍÆÏÑÖPÐØ×ÚÙ ÛÝÜ/ÞÓÜ ÏÑÖ/ÐÓ×ÚÙ

ÛÝÜ Õ ÔÍÆÏÑÖ/ÐÓ×ÚÙ

Figura1.4: Grafodi ereditarieta

Capitolo 2

Il linguaggio Java

In questocapitolovengonorichiamatibrevementei concettidel linguaggioJava.Il linguaggioJava none un linguaggioobject-orientedpuro, mail suonucleobase,costituitodai tipi basee dalle

istruzioni, rispecchiail modellocomputazionaledei linguaggi procedurali. E a livello delle classiche si utilizzapienamentela programmazione orientataagli oggetti. Questadicotomiatra i duelivelli checomporta l’uso di dueparadigmi differenti complica la programmazione, comesi puo vedere dal fatto che vengonodefinite delle classiutilizzateper rappresentarei tipi basea livello di classe.Datochesi ha sia il tipo baseint chela classeInt perrappresentaregli interi, qualesi usa?

2.1 Commento

In java e possibilescrivere i commenti al codicein tre forme:// commento da// fino a fine linea/* commento */ tutti i caratteri tra /* */ inclusi

/** commento*/commento di documentazioneprimadichiarazionedi classiodelementidellaclasse.E utilizzatodatool di generazioneautomaticadelladocu-mentazione (javadoc)

2.2 Dichiarazionedi variabile

In Java le variabili vengonodichiarate conla seguentenotazione:

<tipo> <listad iidentifica tori>;

Il tipo puo essereseguito daunao piu coppiedi parentesiquadreapertee chiuse[] perindicarechela variabile eun array. Il numerodellecoppiedi parentesidefiniscela dimensionedell’array. Perogni dimensione l’indice cheneindividuale componentivada0 a N-1 doveN e il numerodi tali componenti.

Il tipo e un tipo baseoppure unaclasse.Il valore chepuo assumereunavariabiledipendedal tipo. Nel casodeitipi basee un valore definitoper il tipo, mentrenel casodi unaclassee un riferimento adun oggettoappartenenteataleclasseo sottoclasse,oppure il valorenull perindicare chela variabilenonsi riferisceanessunoggetto.

Peraccedereal valore memorizzato in unavariabile si usail nomedellavariabile,oppure,nel casodi un array,il nomepuo essereseguito daelementidenotaticon [i] dove i e unaespressionedi valore intero. In tal casoognielementoindividuala componentei-esimadelladimensionek-esima, conk il numerod’ordinedell’elemento [i] .

La dichiarazionedi variabilepuo essereprecedutadaparole chiavi chedefiniscono alcunecaratteristichequali loscope.Unavariabile puo essereinizializzatafacendoseguire il nomedaun= edunaespressionela cui valutazionedail valoredi inizializzazione.Nelcasodi un arrayi valori dei singoli elementi sonoseparatidavirgola e racchiusitraparentesigrafe

2.3 Tipi

Un tipo e caratterizzatodatreelementi:

� insiemedeivalori rappresentatidal tipo

� operazionieseguibili sutali valori

6 2. Il linguaggio Java.

� costantirappresentatein qualche formalismosintattico

In Jaß

va i tipi possonoesseredivisi in duecategorie:

tipi base sonoi tipi definiti dal linguaggio stessodi cui fanno parteintegrante. L’insiemedei valori, le operazioni ele costantisonoprestabiliti enonsonomodificabili.

classi l’insiemedei valori e le operazionipermessesonodefiniteattraversoopportunenotazioni sintattiche.Inoltrevieneestesosecondoi meccanismidell’eriditarieta, nel sensocheil tipo associatoad unaclassecomprendeanchele superclassie le interfaccechela classeimplementaconle loro superinterfacce.Nonesistela possibilitadi definire costantisenonin qualchecasoisolato(adesempiola classeString)

2.4 Tipi base

byte interi 8-bit complementoadue

short interi 16-bit complementoadue

int interi 32bit complementoa due

long interi 64bit complementoa due

float reali 32bit IEEE754-1985

double reali 64bit IEEE754-1985

char caratteri16bit in codiceUnicode

boolean costantitrue o false

2.5 Costanti

In javasi possonoesprimerei seguenti valori costanti:

valori booleanle costantitrue e false

valori interistringhedi cifre ottali, decimalio esadecimali.I simboli iniziali dichiaranola basedel numero: seinizia per0la basee ottale,seinizia per0x o 0X la baseeesadecimale, in ognialtrocasola baseedecimale. Sela costantee seguitadallaletteral o L edi tipo longaltrimentidi tipo int.

valori realile costantireali sonoespressecomestringhedi cifre decimaliconun puntodecimaleseguitedaun esponenteopzionaleprecedutodallaletteraeo E. /possonoessereseguitedallaletteraf o F perindicareil tipo float,oppuredallaletterad o D peril tipo double. Senonvi e l’indicazioneesplicitadel tipo vieneassuntoil tipo double.

carattericarattericostantisonoespressiconun simbolotra apici come’A’. alcunicaratteri possonoessererappresentatimedianteunasequenza (valori traparentesicorrspondonoalla codificaUnicode):

\n newline (\u000 A)\t tab(\u0009 )\b backspace (\u0008 )\r return(\u000D )\f form feed(\u000C )\\ backslash(\u005 C)\’ apice(\u0027 )\" doppio apice(\u0022 )\ ddd rappresentazioneottaledelcarattere

riferimento ad oggettila costantenull rappresentaunriferimento all’oggettochenonesiste,ovvero none un riferimentovalido.

stringhei caratteriracchiusi tra doppi apici (”) sonole costantidel tipo String, chee unaclasse.

2. Il linguaggio Java. 7

2.6 Classi

Unaà

classee compostadaun insiemedi variabili e daun insiemedi metodicherappresentanoil codiceperelaborarel’info rmazionecodificatanellevariabili.Unaclassepuo estendereun’altraclasse,la suasuperclasse,e/oimplementaredelleinterfacce.

La sintassi:

[public | abstract | final] class <id> [extend s <classid> ][implements <interface id list>]

{

<dichia razione di variabili><dichia razione di metodi>

}

dove:

public classeaccessibiledall’esterno

abstract la classenon puo essereistanziata,puo esseresolo utilizzatacomesuperclasse.Definiscedegli elementi(variabili ometodi) abstractchedevonoessererealizzatidallesottoclassi.Definizioneparzialedell’implementazione.

final la classenonpuo essereutilizzatacomesupeclasse,ovvero none possibileclassiderivate daunaclassedefinitafinal.

extends clausolaopzionalechedefiniscela superclassedacui la classeeredita.Senonpresente,perdefaultsi ereditadallaclasseObject.

implements clausolachedefiniscele interfaccechela classeimplementa.

2.6.1 Opzioni per variabili emetodi

Nelledichiarazionidi variabili emetodipossono esserepresentidelleopzioni espresseattraversola presenzadi parolechiavechemodificanole caratteristichedegli elementi.Controllodelloscopeedereditarieta.Le keyword sonoin alternativa.

public gli elementisonoaccessibiliovunquela classee accessibilee possonoessereereditati dallesottoclassi

pri vate gli elementisonoaccessibilisoloall’interno dellaclasse

protected gli elementisonoaccessibilisolamentenellaclassee suesottoclassi

final gli elementinonpossono piu essereridefiniti.

nel casononci sianessunadi questeparole chiavegli elementisonoaccessibilidasottoclassinellostessopackage

Elementidi classe.

static elementi dichiarati con questa opzione appartengono alla classe. In altri termini nel casodi variabili sonovariabili di classeovvero e unicaindipendementedaqunatisonogli oggetti istanziati.Nel casodi metodisonometodi di classee possonoessereattivati utilizzandocomeriferimento l’identificatore di classe.Inoltre nonepossibileusarele variabili this esuper nel loro corpo.

Programmazione concorrente

synchronized definiscemetodi di unaclassechenonpossonoessereeseguiti in parallelo. Levarieattivazioni vengonoserializzate.

volatile definisceunavariabilechepuo esseremodificatain manieraasincronarispettoall’esecuzione di un thread

Metodinativi

native definisceunmetodoscrittoin unaltro linguaggio (adesempioC).

8 2. Il linguaggio Java.

2.6.2 Variabili

Si puo accedereá alle variabili dichiaratepublicconla notazione

oggetto .variabile

mentre sesonostatic

classe. variabile

Si possono esprimere valori costantidefinendo variabili public staticfinal convalori di inizializzazione.

2.6.3 Metodi

Sintassi:

<tipo> <metodoId> ( < lista parame tri> )throw <excep tionList>

{ <body> }

dove

<tipo> e il tipo del valoredi ritorno del metodo. Puo essereun tipo base(ritorna un valore corrispondente), unaclasse(ritornaun riferimento adun oggetto appartenentea taleclasseo sottoclasse)oppurevoid ( nonritornanessunvalore)

<metodo Id> identificatoredelmetodo

<lista parametri> lista di parametri formali separatidavirgola. Ogni parametroe formatodaunacoppia tipovariabile.I parametri sonopassatipervalore.

<except ionList> lista di eccezioni, separateda virgola, chepossono esseregenerate durantel’esecuzione delmetodo

<body> corpodelmetodoformatodadichiarazionedi variabili locali e istruzioni

Ogni metodoe univocamenteindividuatodal suonomee dal numero e tipo dei parametri. Quindi si possonoavereduemetodiconlo stessonome (overloading).

Attivazionedi unmetodo:

<riferi mento>.<met odoId>(<lis ta paramet ri attuali> )

dove

<riferi mento> definiscel’oggettoa cui vieneapplicatoil metodo. Puo essereunavariabile, un identificatore diclasse,o un’espressionecheritornaunriferimento adunoggetto.

<metodo Id> e l’identificatore delmetodo

<lista parametri attual i> listadi espressioni,separatedavirgola,i cui valori sonoassegnatiai corrispon-dentiparametri formali

All’interno del corpo di unmetodo e possibileutilizzareduevariabili predefinite:

this contieneil riferimento all’oggettosucui il metodo estatoinvocato

super contiene il riferimentoall’oggettosucui il metodoe statoinvocatocomeistanzadellasuasuprclasse.In altriterminiattraversola variabile superepossibileaccedereai metodidellasuperclasse.

2. Il linguaggio Java. 9

2.6.4 Creazionedi oggetti

Gliâ

oggetti vengonocreaticonla seguente notazione:

new <tipo>

dove

<tipo> e un tipo baseodunaclasse.Il tipo puo essereseguitodaunvalorenumericoracchiusotraparentesiquadrechepuo asuavoltaessereseguitodallamedesimastruttura.Nel primo casovienecreatounarrayconunnumerodi elementideldatotipo parial valorenumerico, mentrenelsecondo unarrayof arrays.

All’interno di unaclassepossonoesseredefiniti dei metodi(constructor)chevengono attivati in maniera implicitaalla creazione di un oggetto. Il loro identificatore e ugualea quellodellaclassee possonoaveredei parametri. Sonoutilizzati perfunzioni di inizializzazione. L’usodellavariabilethis al loro interno nelformatothis(<event ualiparametri >) attiva il corrispondente costruttore dellamedesimaclasse,mentrel’uso dellavariabile super nellaforma super(<eve ntuali parametri >) attiva il corrispondentecostruttore dellasuperclasse.Nel casoin cuinonvi siail costruttore i valori dellevariabili sonoinizializzatiai valori definiti nelledichiarazionio avalori di default.

2.6.5 Interfacce

Datocheil linguaggio javahasolamenteereditarietasingolal’uso delleinterfaccepermettedi ovviareataleproblemaintroducendounametodologia chepresentacaratteristiche simili all’ereditarieta multipla, ma checomunquenon laequivale.

La sintassiperla definizionedi unainterfacciaesimile quellausataperdefinire unaclasse:

interface <id> [extends <inter faceid list>]{

<defini zione di variabi li><defini zione di metodi>

}

main questo casononnonvienedefinito il corpodei metodi,dei quali si dichiara solamentel’intestazione.Inoltrele variabili devonoaverevalori di inizializzazionee sonoconsideratedellecostantiil cui valore nonpuo esseremod-ificato. La dichiarazionecompleta del metodoconil relativo corpovienedemandataalla classecheimplementa unainterfaccia.Un esempiodell’usodelleinterfaccee propostonell’esempioEreditarieta multipla.

2.6.6 Classiinterne (inner classes)

E possibiledefiniredelleclassiin ogni scope,ovverocomemembri di altreclassi,localmente all’internodi unbloccodi istruzionio in manieraanonima comeelementodi unaespressione.Il loro usoe utile in contestitipo l’AbstractWindow Kit (AWK) perassociareelementidell’interfacciagraficaconazionidaeseguirealla loro attivazione.

2.6.7 Packages

Le classiin java possono essereraggruppatein packageschepermettono di delimitarel’ambito di validita degli iden-tificatori utilizzati in tali classi.Si usail costrutto

package <nome\ _qualificat o> ;

postoall’inizio del file sorgente per assegnare le classiivi definitea tale package. Il <nome qualifi cato> delpackage e formatodaunoo piu identificatoriseparatida. (punto) comedescrittoda:

<nome\_qu alificato> ::= <ident ificatore> [.<identif icatore>]

e definisceil percorsodelladirectoryin cui risiedeil codice compilato di talepackage.In altreparole sostituendoalpuntoil simbolodi separazione perle sottodirectory(adesempioil carattereperUnix) si ottieneil nome della directory, riferita alla directory baseutilizzatadallamacchinavirtuale,dove deverisiedereil codice compilato.

Perpoterutilizzaregli elementidi unpackage si deveutilizzareil costrutto

import <nome\_ package>.* ;

10 2. Il linguaggio Java.

seesistesseroconflitti di nomi conaltri packagessi puo utilizzareil nome del packagecomequalificatore dei nomiconil formato

<nome\_ package>.<n ome\_elemen to>

2.7 Conversioni di tipo

Java e un linguaggio fortementetipizzato.Questosignificacheil compilatoreverificasemprela compatibilita dei tipi.Vi possono essereconversioniimplicite oppureesplicite.

2.7.1 Implicite

Javaeseguein manieraimplicita le seguenti conversioniperi tipi base:

1. char ã int

2. tipi interi ã float

3. float ã double

Nel casodi riferimentiadoggetti, si puo usareil riferimento adunoggetto di unacertaclasseovunquesiarichiestounriferimentoadunasuasuperclasse.Infine, vi eunconversioneimplicitaadoggetti di tipoString.I tipi basevengonoconvertiti astringhecherappresentanoil loro valore,mentrepergli oggetti si usail metodotoString.

2.7.2 Esplicita

Attraversol’espressione

(<tipo> )<espressio ne>

e possibileconvertirein manieraesplicitaunvalore di uncertotipo in unaltro tipo.Nel casodei tipi basee possibileconvertire tipi con maggior precisione in tipi con minor precisione, quindi ,adesempio, long in int, double in float, tipi reali in tipi interi. Non e possibileconvertirealcuntipo nel tipo boolean.Nel casodi oggetti, e possibileconvertireunriferimento daunaclasseadunaltrachesiasottoclassedellaprimasolosel’oggettoindividuatodal riferimento e un istanzadellasecondaclasse.SequestononfosseveroverrebbegenerataunaeccezioneClassCastEx ception . E possibileverificarel’appartenenzadi un oggettoadunacertaclasseconl’operatoreinstanc eof :

<oggett o> instance of <tipo>

cheritorna true sel’oggettoappartiene al tipo, false altrimenti.

Listato 2.1- TypeCast.java: conversionedi tipi esplicita.

class Data{}

class DataA extends Data {}

class DataB extends Data {}

public class TypeCas t{

public static void main(){char c=’A’;byte b=13;short s=1024;int i=0x0fffff ff;long l=0x0ffff ffffffL;

2. Il linguaggio Java. 11

float f=1.5f;double d=3.5567 890754334D;

// conversioni implicite da chari=c; l=c; f=c; d=c;

// conversioni implicite da byte

s=b; i=b; l=b; f=b; d=b;

// conversioni implicite da intl=i; f=i; d=i;

// conversioni implicite da longf=l; d=l;

// conversioni implicite da floatd=f;

// non esiste nessuna conversione implicita da double ad altri tipi

// tutte le rimanenti conversioni devono essere fatte in maniera esplicita

// da charb=(byte)c ; s=(short)c ;

// da bytec=(char)b ;

// da intc=(char)i ; b=(byte)i;

// da longb=(byte)l ; c=(char)l; i=(int)l;

// da floatc=(char)f ; b=(byte)f; s=(short)f; i=(int)f; l=(long )f;

// da doublec=(char)d ; b=(byte)d; s=(short)d; i=(int)d; l=(long )d;

Data data;DataA dataA = new DataA();DataB dataB = new DataB();

data = dataA; // conversion e implicita da sottoclas sedataA = (DataA) data; // conversio ne esplicita da supercla ssedataB = (DataB) data; // conversio ne esplicita da supercla sse. durante l’esecuzion e

// viene segnalata l’eccezione ClassCastEx ception

/* le seguenti conversioni non sono permesse, generano errore in compilazio ne

dataA = (DataA) dataB;dataB = (DataB) dataA;*/

}}

12 2. Il linguaggio Java.

2.8 Espressionied operatori

2.8.1 Precedenzadegli operatori

postfissi [] . ( parametri) espr++ espr--unari ++espr-- espr+espr- espr ˜ !creazione/conv. tipo new ( tipo) esprmoltiplicativi * / %additivi + -shift << >> >>>relazionali < > <= >= instance ofuguaglianza == !=AND bit &XOR bit ˆOR bit |AND logico &&OR logico ||condizionale ?:assegnazione = += -= *= /= %= >>= <<= >>>= & = ˆ= |=

2.8.2 Associativit a

Tutti gli operatori binari tranne che quelli di assegnazione sonoassociativi a sinistra(left-associative). Quelli diassegnazionesonassociativi adestra(right-associative).

2.8.3 Ordine di valutazione

Il linguaggio Java garantiscechegli operandi sonovalutatidasinistraa destra.

2.8.4 Operatori aritmetici

+ addizione(binario),segnopositivo(unario)- sottrazione(binario), negazione(unario)* moltiplicazione/ divisione% resto++ autoincrementoprefissoo postfisso-- autodecrementoprefissoo postfisso

2.8.5 Concatenazionedi stringhe

+ concatenazionedi duestringhe

2.8.6 Operatori di confronto e logici

> maggiore< minore>= maggioreuguale<= minore uguale== uguale!= diverso&& andlogico|| or logico! not logico

Nell’and e or logico la valutazione del secondo operando e condizionaleal valore nel primo, ovvero vienevalutatosolamente senecessario.

2. Il linguaggio Java. 13

2.8.7 Operatori sui bit

& andbit a bit| or bit a bit˜ complementoauno<< shift a sinistraintroducendozeri>> shift a destraaggiungendo bit di segno>>> shift a destraintroducendo zeri

Gli operatori and, or e complementopoossonoessereapplicatisolamentea tipi interi o booleani, quelli di shift soloatipi interi.

2.8.8 Operatori di assegnazione

In java l’assegnazioneeunaespressionecheritornacomevalore il valore assegnato.Datounoperatoreop=, si hachel’espressione

varop= expr

equivalea

var= varop (expr)

eccettochevar e valutataunasolavolta.

2.9 Eccezioni

Unaeccezionee generataquando avvieneun errore durante l’esecuzione. Le eccezionisonooggetti definiti daclassicheestendono la classeThrowable.

Eccezioni sonodi solito ”checked exceptions”, chesignificache il compilatore verifica che i metodigenerinosolamentele eccezionichedichiarano. Errori standarddi esecuzione estendono le classiRuntimeExceptione Error,chesono”unchecked exceptions”. Per convezione, nuove eccezioni devono esseredefinitecomeestensionedellaclasseException, rendendoledi tipo ”checked”.

Esistonoistruzionipergenerare eccezioni(throw ) edistruzioni pergestirle(try-cat ch-finally ).

2.10 Istruzioni

espressionstatementsogni espressionechesiadi unodei tipi seguenti:

� espressionedi assegnazione� espressionicongli operatori++ e --� attivazione di metodi� creazioni di oggetti (operatorenew)

puo diventareun istruzioneseseguitadapunto evirgola (; )

bloccozeroo piu istruzioniracchiusedaparentesigrafe ({ } ) compongono unblocco

if (boolean expr) istr1 elseistr2seil valore dell’espressionebooleanae truevieneeseguital’istruzioneistr1 altrimenti istr2. La clausolaelseeopzionale.

switchvaluta unespressioneinterail cui valoree utilizzatoperscegliereunaappropriataclausolacase .

switch ( int-expr){case costante-int : istr-listcase costante-int : istr-list.......default: istr-list}

14 2. Il linguaggio Java.

Seesisteun case il cui valore costantecorrispondealla valutazionedell’espressione,si continua l’esecuzionecon la primaistruzionechesegueil case . Senonvi e, si saltaall’istruzionecontrassegnatadadefault sepresente,altrimentisi saltal’intera istruzione switch .

while (boolean-expr) istrFinchela’espressionebooleanaeverasi eseguel’istruzioneistr. L’istruzionenonvieneeseguitasel’espressionebooleana e inizialmentefalsa.

do istr while (bool-expr);Si continua ad eseguire l’istruzione istr fino a quando l’espressionebooleanadiventa falsa. L’istruzione istrvieneeseguitaalmenounavolta.

for (init-expr-list;boolean-expr;inc-expr-list) istrequivalenteal seguentesegmentodi programma:

init-expr-list;while ( boolean-expr ){

istr;inc-expr-list;}

dove inc-expr-list e unalista di espressioni,separatedavirgola, chevengonovalutatesequenzialmente.

breakpuo essereusatoperusciredaun bloccoqualunque.Nella maggiorpartedei casie utilizzatoperterminare unciclo. Puo essereseguito daunalabel,ovverodaun identificatore, chepermettedi individuareunaparticolareistruzioneconla notazione label: istruzione. Nel casosenzalabelil breaktermina il bloccopiu interno, mentrenel formatoconla labeltermina il bloccocontrassegnatodatalelabel.

continuesaltaallafinedelcorpodi unciclo facendo partireunasuccessiva iterazioneconla valutazione dell’espressionebooleanachecontrolla il ciclo. Nel casononsiaseguitodaunalabel,si applicaal ciclo piu interno, altrimentiaquellocontrassegnatodallalabel.

return exprterminal’esecuzione di un metodoassegnando comevalore di ritorno il valore dell’espressioneexpr. Se ilmetodononritornanessunvalore(tipo di ritornovoid ) nonci deveesserealcunaespressione.

thr ow exceptiongeneraunaeccezione rappresentatadall’oggettoexception.

try- catch-finallyutilizzatopergestirele eccezioni.

tryblocco

catch ( tipo-eccezioneidentificatore)blocco

catch ( tipo-eccezioneidentificatore)blocco. . . .

finallyblocco

Il bloccodel try vieneeseguitofincheo avvieneunaeccezioneoppureil bloccoterminaconsuccesso.Nel casoin cui siagenerataunaeccezione,vienebloccatal’esecuzionedelbloccodel try esi cercaunaclausolacatchcheabbiacometipo-eccezionela classeo unasuperclassedell’eccezionegenerata. Seesistetale clausola,siassociaal corrispondente identificatore l’eccezione e si esegueil blocco associato.Senon vienetrovato unaclausolacatch appropriata,l’eccezionevienepassataaaun eventualeistruzione try cheincluda l’istruzionetry corrente. Senonesistealcunaclausolacatch chepossagestirel’eccezione, vienepassataal codicecheaveva invocato il metodo. Il codicedellaclausolafinally vienesempreeseguito al terminedell’esecuzione

2. Il linguaggio Java. 15

del try sia nel casodi successosia nel casodi eccezione. Quest’ultimo codicepuo modificare il valore diritorno dell’istruzionetry conl’utilizzo di unaistruzionereturn o generandounaeccezione chesostituiscel’eventualeeccezione generatadurantel’esecuzionedelbloccodel try .

16 2. Il linguaggio Java.

Capitolo 3

Programmi procedurali.

Nei programmipresentatiin questocapitolosi e utilizzatounostile di programmazioneprocedurale.Questosignificachenonsonostateutilizzatele caratteristicheobjectorientedpresentiin Java. Ovviamentesi ritrovera la definizionedi qualcheclasse,matali classivengonoutilizzatesolamentecomecontenitori per i metodi,percui adesempiononvengonomaiinstanziate.Talestileesimilequello utilizzatoperprogrammarein PascaloC.Rispettoaquestilinguaggiil vantaggio di usareJavastanellapossibilitadi sfruttare il polimorfismoperapplicare il medesimonomedi metodo adatidi tipo differente,comeverradescrittonelprogrammaFattorialepolimorfo ”overloaded” a pagina 26.

3.1 Programmi banali

In questasezionevengonomostratidueprogrammi alquanto banali. Il primo nonfa assolutamente niente,mentre ilsecondostampaunmessaggioaterminale. Anchesesembranoassolutamenteinutili, vengonospessousaticomeprimiprogramminei libri di programmazione.In speciela secondaversioneepresentein tutti i libri in varianti praticamenteuguali, cambia solamenteil messaggio, edovviamantequestolibercolononfaeccezione.Un altro loro possibileusoecomeprogrammidi provaperunambiente di programmazione,essenzialmentepervedere sesi e capacidi compilareedeseguireunsempliceprogramma.

Listato 3.1- Niente.java - programma minimo in Java.

/**** programm a minimo in Java** @author P.Bison Copyright 1997**/public class Niente {

/*** programm a principale. Programma che non fa niente.*/

public static void main(Strin g[] args) {}

}

Il minimo programmachesi possascrivere in Java e mostratonel listato 3.1. Da questosempliceprogrammasipossonovedere i dueelementiminimi chedevono esserciin unaapplicazione Java: la definizione di unaclasseela dichiarazione del metodo main chee il punto di attivazione dell’intero programma. Il sistemaa cui sara datoilcompito di attivarequestaapplicazione cedera il controllo al metodomain cheiniziera l’esecuzione. E obbligatoriochela definizionedelmetodo main seguala strutturamostratanel listato,altrimenti vienesegnalatounerrorequandosi inizia l’esecuzione. Il parametro args e un arraydi stringhechecontienegli argomenti del comando chee statousatoperattivarel’applicazione.

L’esecuzionedi questoprogrammaovviamentenondaraalcunsegnovisibile dellapropria esecuzione. Sesi vuoleaverequalcheindicazionedi unaavvenutaesecuzionesi puo modificareil programmaaggiungendounaistruzionechestampaunmessaggiosul terminale,comemostratonel listato3.2.

Listato 3.2- SciavoVostro.java - semplicestampa.

18 3. Programmi procedurali.

/**** programma minimo in Java che stampa <b> Sciavo vostro! </b>** @author P.Bison Copyright 1987**/public class SciavoVos tro {

/*** programma principal e*/

public static void main(Str ing[] args) {System.out.p rintln("Sciav o vostro!"); //stamp a il messaggio .}

}

In questocasol’istruzioneSystem .out.printl n("Sciavo vostro!"); stampail valoredelparametro,in questocasola stringa"Sciavo vostro! " , seguitodaunacaposul terminale.Si interpretataleistruzionecomel’attivazionedel metodo println dell’oggettooutdellaclasseSystemconil parametro "Sciavo vostro!" .

Per inciso, la fraseSciavovostro era un salutoutilizzato nella SerenissimaRepubblicadi Venezia,da cui perelisioneederivatol’attualesalutoinformaleCiao.

3.2 Stampadegli argomenti.

Il programmamostratonel listato3.3stampaa terminale gli eventuali argomentipassatiall’applicazionedalcomandodi esecuzione.

Listato 3.3- Eco.java - stampadegli argomenti.

/**** stampa degli argomenti a terminale. Stampa degli argomenti passati al programma* dal commando di esecuzione , uno per linea.** @author P.Bison Copyright 1987**/

public class Eco {

/*** programma principal e*/

public static void main(Str ing[] args) {

for(int i=0; i < args.leng th; i++) // itera sul numero di argoment iSystem.out.p rintln(args[i ]); //stampa l’i-esi mo argomento.}

}

Un ciclo for e utilizzatoper iteraresul numero degli argomentipassatial programma.La variabilei e l’indiceutilizzatoperscorrere i singoli argomentie variada0 a n-1, dove n e il numero di argomenti passatial programmanell’esecuzionecorrente. Talenumero vienecalcolatoattraversola notazione args.lengt h cheritornail numerodi elementipresentinell’array args . Tale notazione si puo applicare a qualunquearraypervalutareil numero deisuoicomponenti.All’usualeistruzionedi stampavienepassatocomeparametro l’i-esimo argomentochevienequindistampatoa terminale seguito daun a capo. Si noti chegli argomenti sonostringhepercui sesi volessepassaredeivalori numerici si devono usareappositi metodi, tipo parseInt della classeInteger, per convertire l’argomentonelcorrispondente valore numerico.

3. Programmiprocedurali. 19

3.3 Programmi sulle stringhe

Nelä

primo esempio,mostratonel listato 3.4, si verifica in maniera iterativa seunastringae palindroma, ovvero serisultaugualesialeggendoladasinistrachedadestra.Utilizzandoun ciclo for si scorrela stringasiadall’inizio chedalla fine utilizzando i dueindici i e j . Il valore ottenutoconfrontando i duecaratteriindicati da tali indici vienememorizzatonelflag isPalin Flag chealla fine indicasela stringae o none palindroma.

Listato 3.4- Palin.java - verifica seuna stringa e palindr oma.

/**** verifica se una stringa e’ palindroma** @author P.Bison Copyright 1987**/

public class Palin {

public static boolean isPalin(S tring st) {boolean isPalinF lag;int i,j;

i=0; j=st.length ()-1;isPalinFla g = true;while((i<= j) && isPalinFlag)

isPalinF lag = st.charAt(i++) ==st.charAt(j --);return isPalinFl ag;

}

/*** programm a principale*/

public static void main(Strin g[] args) {

for(int i=0; i < args.length ; i++){ // itera sul numero di argomentiSystem.out.pr int(args[i]);if (isPalin(a rgs[i])) System.out. println(" e’palindro ma");else System.o ut.println(" non e’palindro ma");}

}}

Nell’esempio riportatonel listato3.5si calcola,semprein manieraiterativa, il rovesciodi unastringa, ovvero lastringaottenutaleggendo la stringadi partenzaa rovescio.Utilizzandoi metodiconcat e substring definiti perla classestring , attraversoun ciclo for chescorretutta la stringapartendo dall’ultimo carattere,si concatenanoisingoli caratteridall’ultimo al primo.

Listato 3.5- Reverse.java - capovolge una stringa.

/**** esegue il reverse di una stringa** @author P.Bison Copyright 1987**/

public class Reverse {

public static String doReverse( String st) {int i,j;String t = new String() ;

for(i=st.l ength()-1; i>=0;i--)t=t.conca t(st.substrin g(i,i+1));

return t;}

20 3. Programmi procedurali.

/*** programma principal e*/

public static void main(Str ing[] args) {

for(int i=0; i < args.leng th; i++){ // itera sul numero di argomen tiSystem.out.p rint(args[i] + " ");System.out.p rintln(doReve rse(args[i]));}

}}

3.4 Calcolodel fattoriale

Il calcolodel fattorialee un esempiomolto comune nel campodella programmazione. In questocasonel listato3.6 vienemostratala suarealizzazione nel linguaggio java utilizzando un algoritmo iterativo basatosul fatto cheilfattorialedi n e ugualeal prodotto di tutti i numeri da1 an:

åçæuèÁåêé�åìëîíÚïðé°åìëòñ�ïØó�ó�ó�í

Quindi conunsempliceciclo while si puo iteraresututti in numeri tran e1 memorizzando adogni passoil prodottoparzialein unavariabilechealla fine conterra il valore cercato.Si noti inoltre i limiti di questoprogrammariportatinel listatostesso.

Listato 3.6- Factorial.java - fattoriale iterativo.

/*** calcolo del fattoriale con algoritmo iterativ o.** @author P.Bison Copyright 1997*/

public class Factorial {

/*** fattoriale iterativ o con risultat o e parametro di tipo int.* calcola il fattoria le del numero passato come parametro.* utilizza il tipo int, percui si ha un errato valore di ritorno* quando si supera il valore massimo rappresenta bile* ad esempio il fact(15) risulta 200431001 6 mentre il risultat o* corretto e’ 1307674 368000* risultato e’ corretto fino a fact(12)* @param n valore di cui si deve calcolare il fattorial e* @return il fattoria le di n*/

public static int fact(int n) {int ris;

ris=1;while(n!=0)

ris = ris * n--;return ris;}

public static void main(Strin g[] args) {int n=5;

if (args.lengt h == 1)n= Integer. parseInt(args [0]);

System.out.pri ntln("fact("+ n+") = "+fact(n));}

} // end of class Factorial

3. Programmiprocedurali. 21

3.5 Massimo Comun Divisoredi Euclide

Euclide,un matematicogrecovissutonel IV secoloA.C., nellasuaopera Gli Elementidescrive un algoritmoper ilcalcolodel massimocomundivisore(MCD) di duenumeri. Dati duenumeri - ô e å - il massimocomundivisorediô e å , denotatocon õ�öð÷ é ôùø åúï , e il piu grande numerochedividesia ô che å senzalasciarealcunresto,adesempioõ�öð÷ é�í�ñ ø�û�ü ïUè û . L’algoritmo di Euclide,comee oraconosciuto,consisteneiseguentipassi:

1. se ô e minore di å allorascambiaô con å2. poni ô ugualeal restoottenuto da ô diviso å3. se ô none uguale a 0, ricomincia dalpunto 1, coni nuovi valori di ô e å4. il valoredi å e il MCD

Listato 3.7- MCD.java - MassimoComun Divisore.

/**** Algoritm o iterativo di Euclide per il calcolo del Massimo Comun Divisore.** @author P.Bison Copyright 1997**/

public class MCD{

/*** calcolo del massimo comun divisore con il metodo di Euclide*/

public static int calcolaMCD(in t n, int m){

int t;

while(m!= 0) {if (m<n) {t=m; m=n; n=t;} // scambia m con nm = m % n;}

return n;}

/*** programm a principale*/

public static void main(Strin g[] args) {int m=24,n=12, mcd;

if (args.lengt h == 2) {m= Integer.p arseInt(args[0 ]);n= Integer.p arseInt(args[1 ]);}

mcd=calc olaMCD(m,n);

System.o ut.println(mc d);}

}

22 3. Programmi procedurali.

3.6 Cri vello di Erastotene.

Erastotene(276-196A.C.) invento unmetodo efficientepercostruiretabelledi numeri primi. Talemetodoechiamato”Crivello di Erastotene“ epuo esseredescrittonellamaniera seguente.

Si scriva unalista di interi checominciper2 e chetermini conun qualche numero, per esempio23. Il metodopermettedi trovare tutti i numeri primi compresitraquestiduevalori.

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Partendodalprimonumero, in questocasoil valore2, si marchi tutti i multipli di talenumero:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23x x x x x x x x x x

Si consideriil successivo numerononmarcato,in questocaso3, e si marcitutti i suoimultipli:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23x x x x x x x x x x x x x

Si continui i questamaniera,marcandotutti i multipli dei successivi numerinonmarcati finche nonrimane alcunnuovo numero non marcato. I numeri chenon risultanomarcatisononumeri primi. Nell’esempio la tabellafinalecorrispondeall’ultima tabelladatapercui i numeri primi sono:

2 3 5 7 11 13 17 19 23

Il programmajava cherealizzaquestoalgoritmo emostratonel listato3.6.8.

Listato 3.8- Sieve.java - il crivello di Erastotene.

/**** Crivello di Erastot ene. Calcola i numeri primi con il metodo* del crivello di Erastotene . L’argomento, se presente, da* il valore massimo entro cui calcolare i numeri primi. Se non* e’ presente si usa il valore 23** @author P.Bison Copyright 1997**/

public class Sieve{

/*** calcolo dei numeri primi con il crivello di Erastoten e*/

public static void sieveMetho d(boolean[] flags){

int i,multipl o;

for(i=2; i<flags .length; i++) // inizializz a l’arrayflags[i]=true ;

for(i=2; i<flags .length; i++) { // itera su tutti i numeriif (flags[i]) // se non e’ stato marcato

// marca tutti i suoi multiplifor(mul tiplo=i+i; multiplo<f lags.length; multiplo+=i)

flags[multip lo]=false;}

}

/*** programma principal e*/

public static void main(Str ing[] args) {

3. Programmiprocedurali. 23

int size=23;boolean[ ] flags;

if (args.lengt h > 0) size= Integer .parseInt(args [0]);flags = new boolean[s ize+1]; // array indicizza to da 0 a size

sieveMet hod(flags);

for(int i=2; i <= size; i++) // itera sul numero di argoment iif (flags[i]) {

System.out. print(i); //stampa numero primo.System.out. print(" ");

}System.o ut.println();

}}

Oltreal programmaprincipalemain , nellaclasseSieve e dichiaratoil metodoSieveMethod cheimplemental’algoritmo di Erastotene.

Il programmaprincipale dichiaraduevariabili: size checontieneil valoremassimochesi deveconsiderareperlaricercadeinumeri primi e flags , unarraydi boolean, cheassociaadogninumero, rappresentatodalcorrispondenteindice,il fattodi essereprimoo no: unvaloretrue nellai-esimaposizioneindicacheil numeroi eunnumero primo.

All’inizio sevi sonoargomenti passatiall’applicazionesi valuta il primo argomentocomeinteroe lo si assegnaalla variabile size . Senonci fossealcunargomentosi usail valore 23, chee il valoredefinitonelladichiarazionedellavariabile stessa.Poi si allocaun arraydi dimensione pari a size+1 . Questoperche la prima posizionedi unarraye indicizzatadal valore 0, quindi sesi vuolechel’indice corrispondaal numeroe cheil massimonumero sia ilvaloredi size si deveallocareunnumerodi elementiparial numero massinodaconsiderare piu uno.Si noti inoltrechevengonoeffettivamenteutilizzatele posizionidall’indice2 al valoredefinitodasize .

Dopo aver attivatoil metodosieveMeth od passandogli comeparametro l’array flags , si stampanoqueinu-meri indicati comeprimi dal fattochela loro corrispondenteposizionenell’array flags contiene il valore true .

Il metodosieveMeth od utilizza duevariabili locali: i confunzionedi indicechescorresui singoli numeri davalutare e multiplo chedatoun numeroiterasututti i suoimultipli inferiori al valore massimo.Inoltre al metodovienepassatocomeparametro l’array cherappresentala proprietadi essereunnumero primo.

Dopo aver inizializzatotalearraya valori tutti true , iterando sututti i numeri daconsiderareattraversoun ciclofor , si valutaseun numerononsiastatomarcato, ovverola corrispondenteposizione nell’array e false . Secio everosi marcando tutti i multipli di talenumeroconunulterioreciclo for .

3.7 Divisioneesatta

L’algoritmo realizzatonel programmapresentato in questasezionerisolve il problemadi calcolarein manieraesattal’inverso per ciascunodei primi 50 numeri primi. Ovviamentenon potendo usarele primitive definitenel linguag-gio(l’operatore /) dal momento chenonsi otterrebbe unvaloreesatto,si utilizza il classicometodo chesi applicaalladivisioneconcartaematita.

Utilizzando degli arrayper memorizzarele cifre del quoziente via via calcolatee i resti ottenutiad ogni passo,si itera con operazioni di divisioneparziale finche si ottieneun restoil cui valore o e nullo oppure e ugualead unrestogia apparsonei passiprecedenti. Vengono inoltre utilizzatedue variabili interecomeindici di inizio e finedell’eventualeperiodo presente nel quoziente. Infine il programmastampala sequenzadi cifre cherappresentanoilrisultatosottolineandoquelleappartenential periodo.

Listato 3.9- Div50.java - calcolodella divisioneesatta.

/*** calcolo della divisione esatta di 1 / N con n = 2..50** @author P.Bison Copyright 1997**/

public class Div50 {

/*** metodo princip ale

24 3. Programmi procedurali.

*/public static void main(Strin g[] args){

DivisioneEsatt a num = new Division eEsatta();int i;

for(i=2;i<=50; i++) num.divi di(i).stampa() ;}

} // end of class Div50

/***oggetto per rapprese ntare una divisione esatta** @author P.Bison Copyright 1997**/class Divisione Esatta {

int n;int[] cifre;int[] resti;int indice; // indica quale cifra del quoziente si sta calcolando (da 0 a 49)int inizio,fin e; // inizio e fine dell’eventual e parte periodica del numero

// construttore/**

**/Division eEsatta() {

cifre = new int[50];resti = new int[50];indice = -1;

}

/*** controlla se e’ terminata la divisione, ovvero se l’ultimo resto e’* zero oppure e’ un resto che e’ gia apparso precedente mente* inoltre calcola l’eventual e periodo*/

boolean finito() {boolean f;int i;

f = resti[indi ce] == 0;if (!f) {

for (i = 0; i <= indice-1 ; ++i)if (resti[i] == resti[indice]) {

f = true;inizio = i + 1;fine = indice;

}}return f;

}

/*** calcola la division e esatta 1/n* @param n denominato re della frazione* @return l’oggetto stesso (this)*/

Divisione Esatta dividi(int n) {int i;

this.n = n;indice = 0; // la prima cifracifre[0] = 0; // e’ zeroresti[0] = 10; // con resto 10inizio = fine = -1; // senza periodo

while (!finito ()) {indice++ ;cifre[indice ] = resti[ind ice-1] / n;

3. Programmiprocedurali. 25

resti[indice] = (resti[indi ce-1] % n) * 10;}return this;

}

/*** stampa il risultato della division e*/

void stampa() {int i;

if (n<10) System.out.pr int("1/ ");else System.out. print("1/");System.out .print(n+" = " + cifre[0] +".");

for (i = 1; i <= indice; ++i)System.out.pr int(cifre[i]);

System.ou t.println();// visualizza eventual e periodoif (inizio !=-1) {

for (i = 1; i <= inizio + 8; ++i) System.out.p rint(" ");for (i = 1; i <= fine - inizio + 1; ++i) System.out.p rint("-");System.out.pr intln();

}}

} // end of class DivisioneEsat ta

Eseguendoil programmasi ottienel’uscitaseguente:

1/ 2 = 0.51/ 3 = 0.3

-1/ 4 = 0.251/ 5 = 0.21/ 6 = 0.16

-1/ 7 = 0.142857

------1/ 8 = 0.1251/ 9 = 0.1

-1/10 = 0.11/11 = 0.09

--1/12 = 0.083

-1/13 = 0.076923

------1/14 = 0.0714285

------1/15 = 0.06

-1/16 = 0.06251/17 = 0.05882352 94117647

-------- --------1/18 = 0.05

-1/19 = 0.05263157 8947368421

-------- ----------1/20 = 0.051/21 = 0.047619

------1/22 = 0.045

--1/23 = 0.04347826 08695652173913

-------- --------------1/24 = 0.0416

-1/25 = 0.041/26 = 0.0384615

------

26 3. Programmi procedurali.

1/27 = 0.037---

1/28 = 0.0357142 8------

1/29 = 0.0344827 5862068965517 24137931------------- -------------- -

1/30 = 0.03-

1/31 = 0.0322580 64516129------------- --

1/32 = 0.031251/33 = 0.03

--1/34 = 0.0294117 6470588235

------------ ----1/35 = 0.0285714

------1/36 = 0.027

-1/37 = 0.027

---1/38 = 0.0263157 894736842105

------------ ------1/39 = 0.025641

------1/40 = 0.0251/41 = 0.02439

-----1/42 = 0.0238095

------1/43 = 0.0232558 1395348837209 3

------------- --------1/44 = 0.0227

--1/45 = 0.02

-1/46 = 0.0217391 3043478260869 565

------------ ----------1/47 = 0.0212765 9574468085106 38297872340425 531914893617

------------- -------------- ------------- ------1/48 = 0.02083

-1/49 = 0.0204081 6326530612244 89795918367346 93877551

------------- -------------- ------------- --1/50 = 0.02

3.8 Fattoriale “overloaded”.

Esempiodi “overloading” in cui ci sonopiu metodi di unaclassechehannolo stessoidentificatore. Vengono distintidal tipo dei parametri formali. In questocasosi definiscono varie implementazionidel fattorialea secondadei tipi acui vieneapplicato.

Listato 3.10 - Factorial.ja va - classeFactorial conoverloading dei metodi.

// java1.1

import java.mat h.*;

/*** esempi di calcolo del fattoriale con algoritm o iterativo.** @author P.Bison Copyright 1997*/

public class Factorial {

// costanti di tipo BigIntege rstatic final BigInte ger bigzero = new BigIntege r("0");static final BigInte ger biguno = new BigInteger ("1");

// private constructor// la classe non puo’ essere instanziata

3. Programmiprocedurali. 27

private Factorial () {}

/*** fattoria le iterativo con risultato e parametro di tipo int.* calcola il fattoriale del numero passato come parametr o. utilizza il tipo int* percui si ha un errato valore di ritorno quando si supera il valore massimo rappresentab ile* ad esempio il fact(15) risulta 2004310016 mentre il risultato corretto e’ 1307674368000* risultat o e’ corretto fino a fact(12)* @param n valore di cui si deve calcolare il fattoriale* @return il fattoriale di n*/

public static int fact(int n) {int ris;ris=1;while(n!= 0)

ris = ris * n--;return ris;}

/*** fattoria le iterativo con risultato e parametro di tipo long.* @param n valore di cui si deve calcolare il fattoriale* @return il fattoriale di n*/

public static long fact(long n) {long ris;ris=1;while(n!= 0)

ris = ris * n--;return ris;}

/*** fattoria le iterativo con risultato e parametro di tipo BigInteger.* calcola il fattoriale del numero passato come parametr o. utilizza il tipo BigInteger* percui non si ha alcun limite nella rappresentaz ione del numero ad esempio si puo’* calcolar e il valore fact(500 0)* @param n valore di cui si deve calcolare il fattoriale* @return il fattoriale di n*/

public static BigInteger fact(BigInte ger n) {BigInteger ris;

ris = biguno;while(!n.e quals(bigzero )){

ris = ris.mult iply(n);n = n.subtract (biguno);}

return ris;}

public static void main(String[ ] args) {int nint=5;int nlong=5;BigIntege r nbig = new BigInteger("5 ");

System.ou t.println("fa ct("+nint+") = " + fact(nin t));System.ou t.println("fa ct("+nlong+") = " + fact(nlong));

System.ou t.print("fact ("+nbig.toStr ing() +") =");BigIntege r bignum;bignum = fact(nbig);System.ou t.println(big num.toString( ));}

} // end of class Factorial

28 3. Programmi procedurali.

Capitolo 4

Programmi orientati agli oggetti.

In questocapitolovengonoillustrati alcuniprogrammicheutilizzano le funzionalita orientateagli oggettipresenti inJava.

4.1 Numeri complessi

La classeComplex implementa il concettodi numerorealemediante l’uso di duevariabili di tipo double cherapp-resentanola parterealee quellaimmaginariadi un numerocomplesso.Inoltre nellaclassestessasonodefiniti alcunimetodipercreare, manipolareevisualizzarenumeri complessi.Vi sonoduecostruttori perl’istanziazionedi elementidi tipo Complex: unocreail numerocomplessonullo mentre l’altro lo creaconvalori passaticomeparametri.Altrimetodipermettono di ottenere la parterealeo quellaimmaginaria (metodiparteRealee parteImmaginaria), oppure diconvertireil numero complessoin unarappresentazione testualein formato stringa(metodo toString). Infine vi sonometodicherealizzano le operazionitra numeri complessi(metodi multiply e add) o convalori scalari(metodo scalarchee overloaded in trevarianti).

Listato 4.1- Complex.java - rappr esentazionedei numeri complessi

/*** numeri complessi** @author P.Bison**/

public class Complex{

double parteReale;double parteImmagin aria;

/* constructors *//**

* crea un numero complesso con valori nulli* @param n la dimensione del quadrato*/

public Complex (){

parteReale = parteImmag inaria = 0.0;

}

/*** crea un numero complesso* @param x parte reale* @param y parte immaginar ia

30 4. Programmiorientatiagli oggetti.

*/public Complex (double x, double y){

parteReale = x;parteImmag inaria = y;

}

/*metodi pubblici

*/

/*** ritorna parte reale*/

public double parteReale (){

return parteReal e;}

/*** ritorna parte immaginar ia*/

public double parteImmag inaria(){

return parteImma ginaria;}

/*** somma due numeri complessi* @param x il secondo operando della somma* @return un numero complesso il cui valore e’ this+x*/

public Complex add (Complex x){

return new Complex (parteRea le + x.parte Reale, parteImmagi naria + x.parteIm maginaria);}

/*** moltiplica due numeri comples si* @param x il secondo operando della somma* @return un numero complesso il cui valore e’ this*x*/

public Complex multiply (Complex x){

return new Complex (parteRea le * x.parte Reale - parteImmag inaria * x.parteI mmaginaria,parteReale * x.parteImm aginaria + parteIm maginaria * x.parteReale );

}

/*** moltiplica un numero compless o per uno scalare di tipo double* @param x il valore scalare* @return un numero complesso il cui valore e’ x*this*/

public Complex scalar (double x){

return new Complex (parteRea le * x, parteImmag inaria * x);}

/**

4. Programmiorientatiagli oggetti. 31

* moltiplica un numero complesso per uno scalare di tipo float* @param x il valore scalare* @return un numero complesso il cui valore e’ x*this*/

public Complex scalar (float x){

return new Complex (parteReal e * x, parteImmagi naria * x);}

/*** moltiplica un numero complesso per uno scalare di tipo int* @param x il valore scalare* @return un numero complesso il cui valore e’ x*this*/

public Complex scalar (int x){

return new Complex (parteReal e * x, parteImmagi naria * x);}

/*** calcola valore assoluto di un numero complesso* @return il valore assoluto*/

public double abs (){

return Math.sqrt (parteReale * parteReale + parteImma ginaria * parteImm aginaria);}

/*** converte un numero complesso in una stringa* @return una stringa che rappresenta il numero compless o*/

public String toString (){

String stReale;String stImmagina ria;

stReale = String.valu eOf (parteRe ale);stImmagin aria = String.valu eOf (parteIm maginaria);return new String (stReale + "+i" + stImmagin aria);

}

/*** metodo principale*/

public static void main (String []args){

Complex num1 = new Complex ();Complex num2 = new Complex (-5.3, 17.56);Complex num3;

System.ou t.println (num1);System.ou t.println (num2);num3 = num2.add (new Complex (-1.2, 0.8));System.ou t.println (num3);num3 = num2.sca lar (1.5);System.ou t.println (num3);System.ou t.println (num3.ab s ());

}

32 4. Programmiorientatiagli oggetti.

} // end of class Complex

4.2 Calcolomatriciale

In maniera simile al casoprecedntesi definiscela classeSimpleMatrixcherappresentale matrici NxM conelementidi tipo reale. Si utilizzanoduevariabili intereper memorizzareil numero di righee di colonne per unaparticolareistanzaedun arraydi arraypermemorizzaregli elementidellamatrice.Al solito si definiscono costruttori percreareelementidi tipo SimpleMatrix, metodi perle operazioni matriciali o conscalariemetodiperla converisoneastringa.

Listato 4.2- SimpleMatrix.ja va - rappr esentazionedi matrici NxM

/*** numeri complessi** @author P.Bison**/

public class SimpleM atrix{

int righe; /* numero di righe */int colonne; /* numero di colonne */double[][] data;

/* constructor s *//**

* crea una matrice 4x4*/

public SimpleMatri x (){

righe = colonne = 4;data = new double[4][4 ];

}

/*** crea una matrice di zeri* @paramn n numero di righe* @param m numero di colonne*/

public SimpleMatri x (int n, int m){

righe = n;colonne = m;data = new double[n][m ];

}

/*** crea una matrice di zeri* @paramn n numero di righe* @param m numero di colonne*/

public SimpleMatri x (double[][ ]initdata){

int i, j;

righe = initdata.len gth;colonne = initdata[0 ].length;data = new double[ri ghe][colonne ];

4. Programmiorientatiagli oggetti. 33

for (i = 0; i < righe; i++)for (j = 0; j < colonne; j++)

data[i][j] = initdata[i ][j];}

/*metodi pubblici

*/

/*** somma due matrici* @param x il secondo operando della somma* @return una matrice il cui valore e’ this+x*/

public SimpleMatrix add (Simple Matrix x){

SimpleMatri x ris;int i,j;

if ((righe != x.righe) || (colonne != x.colonne ))throw new ArithmeticE xception ("Incompa tible matrix");

ris = new SimpleM atrix (righe, colonne);for(i=0;i<r ighe;i++)

for(j=0;j <colonne;j++ )ris.dat a[i][j] = data[i][ j]+x.data[i] [j];

return ris;}

/*** moltiplica due matrici* @param x il secondo operando della moltipl icazione* @return una matrice il cui valore e’ this*x*/

public SimpleMatrix multiply (SimpleM atrix x){

SimpleMatri x ris;double temp;int i,j,k;

if ((righe != x.colonne ) || (colonn e != x.righe ))throw new ArithmeticE xception ("Incompa tible matrix");

ris = new SimpleM atrix (righe, colonne);for(i=0;i<r ighe;i++)

for(j=0;j <colonne;j++ ) {temp=0. 0;for(k=0 ;k<righe;k++ ) temp = temp + data[i][ k]*x.data[k] [j];ris.dat a[i][j] = temp;

}return ris;

}

/*** moltiplica una matrice per uno scalare di tipo double* @param x il valore scalare* @return una matrice il cui valore e’ x*this*/

public SimpleMatrix scalar (double x){

SimpleMatri x ris;int i, j;

ris = new SimpleMatri x (righe, colonne) ;for (i = 0; i < righe; i++)

34 4. Programmiorientatiagli oggetti.

for (j = 0; j < colonne; j++)data[i][j] *= x;

return ris;}

/*** converte un numero complesso in una stringa* @return una stringa che rappresenta il numero comples so*/

public String toString (){

String matrep = "[";int i, j;

for (i = 0; i < righe; i++){

matrep += "[";for (j = 0; j < colonne; j++)

{matrep = matrep + String.v alueOf (data[i][j] );if (j != colonne - 1)

matrep += ",";}

matrep += "]";}

matrep += "]";return matrep;

}

/*** metodo principale*/

public static void main (String[]arg s){

SimpleMatr ix mat1, mat2, mat3;double[][] a ={{1.2, -0.75, 1.8},

{-0.99, 3.45, -4.89},{-9.8, 0.08, 1.98}};

double[ ][] a1 ={{1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{0.0, 0.0, 1.0}};

mat1 = new SimpleMatri x (a1);System.out .println (mat1.toS tring ());mat2 = new SimpleMatri x (a);System.out .println (mat2.toS tring ());mat3=mat2. add (mat1);System.out .println (mat3.toS tring ());mat3=mat2. multiply (mat1);System.out .println (mat3.toS tring ());

}

} /* end of class SimpleM atrix */

4.3 Quadrato magico

Un quadrato magicoperfetto, normale,di ordine å e unascacchieraåþýÝå checontiene nellesue åÈÿ caselleunaedunasolavoltaciascunodeinumeriinteri da1 ad åÌÿ , in modochela sommadegli å valori suogniriga,suogni colonna

4. Programmiorientatiagli oggetti. 35

e suciascunadelleduediagonali principali siala stessa.Questasommavienechiamata costantemagica.Ad esempioil seguentequadratomagicodi ordine5 hapercostantemagicail valore 65.

11 24 7 20 34 12 25 8 1617 5 13 21 910 18 1 14 2223 6 19 2 15

Percostruireunquadratomagicodi ordine å , con å dispari,esisteunalgoritmo di costruzionerelativamentesemplicedovutoa De la Loubere,fondatosuiseguenti quattroprincipi:

� si inserisceil primovalore 1 nellacasellasituataimmediatamenteal di sottodellacasellacentrale;

� sesi e inserito l’intero � ë í nella casella é�� ø�� ï ( con � indice di riga e � indice di colonna), il valoreinterosuccessivo � deveessereinseritonellacasellaé����Áí ø�� � íÚï ;

� senel calcolodi ��Áí oppuredi � � í si ottieneunvalore chesuperaå , taleindicevienepostougualead1

� sesi deve inserireunvaloredi unacasellagiaoccupata(siaadesempiooccupatala casellaé� øZô ï ), si inserisceil valorenellacasellaé��� í ø�ô ë í�ï . Se ô ëîí vale0, si prendecomeindiceil valore å .

Listato 4.3- MagicSquare.java - rappr esentazionedel quadrato magico

/*** implementazi one del quadrato magico** @author P.Bison**/

public class MagicSqu are {

int dim; // dimensio ne del quadratoint[] celle; // vettore che memorizza i valori delle celle.

// e’ compost o da dim x dim elementi e la cella in posizione i,j// e’ indiciz zata da dim x i + j

// constructor/**

* crea un quadrato magico con dimensio ne definita dal parametr o e valori tutti nulli* @param n la dimensione del quadrato*/

public MagicSqu are(int n){int i,j; // indici di cella

dim = n;celle = new int[n * n];

// inizializzaz ione a zerofor(i=0 ;i<n;i++)

for(j=0;j<n ;j++) celle[n * i +j] = 0;

}

// metodi privati

// calcola il success ore per un indice lprivate int succIndex (int l) {

if (l==dim-1) return 0;else return l+1;

}

// calcola il predece ssore per un indice l

36 4. Programmiorientatiagli oggetti.

private int predInde x(int l) {if (l==0) return dim-1;else return l-1;

}

// metodi pubblici

/*** genera i valori magici* @return l’oggetto stesso (this)*/

public MagicSq uare makeMagic(){int i,j; // indici di cellaint k; // indice per il vettore celle (va da 1 a dim x dim)

i = dim / 2 + 1; j = dim / 2;for(k=1; k<= dim*dim;k++ ) {

celle[dim* i + j] = k;

// ricerca successiva cella libera se non e’ l’ultim a

if ( k!= dim*dim ) {i = succIndex( i); j= succIndex(j );while(ce lle[dim*i+j] != 0) {

i = succInde x(i); j = predInde x(j);}

}}

return this;}

/*** calcola la costante magica* @return il valore della costante*/

public int magicCons t(){

int i,j;int magicnum ;int temp;boolean notmagic;

magicnum = 0;

for (i=0;i<d im;i++) magicnum += celle[i]; // somma prima riga

if (magicnum <= 1) return -1; // non puo’ essere magico

// controlla se il valore di magicnu m e’ uguale dappertuttonotmagic = false;for(i=1;i<di m;i++) { // controlla righe

for(temp=0 ,j=0;j<dim;j ++) temp += celle[dim*i+ j];if (notmagic =notmagic || (magicnum!= temp)) break;}

for(j=0;j<di m;j++) { // controlla colonnefor(temp=0 ,i=0;i<dim;i ++) temp += celle[dim*i+ j];

if (notmagic =notmagic || (magicnum!= temp)) break;}

for(temp=0,i =0,j=0;i<dim ;i++,j++) // controlla diagonaletemp += celle[di m*i+j];

4. Programmiorientatiagli oggetti. 37

notmagi c=notmagic || (magicnum! =temp);

for(tem p=0,i=0,j=di m-1;i<dim;i+ +,j--) // control la altra diagonaletemp += celle[dim *i+j];

notmagic =notmagic || (magicnum!= temp);

if (notmagic) return -1;else return magicnu m;

}

/*** stampa la dimensio ne, i valori e la costante magica del quadrato magico* @return l’oggetto stesso (this)*/

public MagicSqu are display( ) {int i,j,k; // contatoriString value;

System. out.println( "Dimensione: "+dim);for(i=0 ;i<dim;i++) {

for(j=0;j<d im;j++) {value = String. valueOf(cell e[dim * i +j]);for(k=0;k <3-value.len gth();k++) System. out.print(" ");System.ou t.print(valu e);}

System.out. println();}

System.ou t.println("C ostante magica: " + magicConst ());System.ou t.println();return this;}

/*** metodo principale*/

public static void main(Str ing[] args){MagicSq uare square1 = new MagicSquare (5);MagicSq uare square2 = new MagicSquare (9);

square1 .display();square1 .makeMagic() ;square1 .display();

square2 .makeMagic() .display();}

} // end of class MagicSqua re

Eseguendoil programmasi ottienel’uscitaseguente:

Dimension e: 50 0 0 0 00 0 0 0 00 0 0 0 00 0 0 0 00 0 0 0 0

Costante magica: -1

Dimension e: 511 24 7 20 3

4 12 25 8 1617 5 13 21 9

38 4. Programmiorientatiagli oggetti.

10 18 1 14 2223 6 19 2 15

Costante magica: 65

Dimensio ne: 937 78 29 70 21 62 13 54 5

6 38 79 30 71 22 63 14 4647 7 39 80 31 72 23 55 1516 48 8 40 81 32 64 24 5657 17 49 9 41 73 33 65 2526 58 18 50 1 42 74 34 6667 27 59 10 51 2 43 75 3536 68 19 60 11 52 3 44 7677 28 69 20 61 12 53 4 45

Costante magica: 369

4.4 Figuregeometriche

In questasezionesi illustra l’utilizzo del concettodi classeastrattaperdefiniredegli elementicomuni adun insiemedi oggettichedovrannoessererealizzatinelle sottoclassidefinentitali oggetti. Inoltre vi e l’uso della funzionalitapackage.

In questoesempiosi considerail casodellefiguregeometrichecaratterizzatedalloroperimetroedareaedaimetodipercalcolare tali valori. Mentrela rappresentazionedel perimetroedareasonocomuni a tuttele figuregeometriche,le procedurepercalcolaretali elementisonoproprie di ciascuntipo di figurageometrica e none possibileaveredeimetodi generali. Quindi si utilizza unaclasseastratta,che non puo essereistanziata,per definire le variabili cherappresentanol’areaedil perimetro e perindicare i metodi chetuttele sottoclassidevvonorealizzare.

Listato 4.4- FiguraGeometrica.java - una classeastratta

package FigureGeomet riche;public abstrac t class FiguraGeom etrica{

float area=0;float perimetro=0;

abstract void calcolaAr ea();abstract void calcolaPe rimetro();

public float getArea(){

if (area == 0) calcola Area();return area;

}public float getPerimetr o(){

if (perime tro == 0) calcolaP erimetro();return perimetro ;

}

}

Data questaclasseastratta,si possono definire delle sottoclassiche rappresentanoparticolati figure geometriche.Questesottoclassioltre a realizzarei metodiimposti dallaclasseastratta,possonoovviamenteintrodurrenuove vari-abili e/ometodi.

La classeTriango lo definiscele proprieta di ungenerico triangolo introducendotre variabili perrappresentarei tre lati di untriangolo erealizzandoil metodo percalcolodelperimetrocomesommadei tre lati e il calcolodell’areaattraversola formuladi Erone.

4. Programmiorientatiagli oggetti. 39

Listato 4.5- Triangolo.java - definizionedi triangolo

package FigureG eometriche;public class Triangol o extends FiguraGe ometrica {

float a,b,c; // i tre lati di un triangolo

public Triangol o(float l1, float l2, float l3){

a=l1;b=l2;c=l3;

}

void calcola Area(){

float p;

p = (a + b + c)/2.0f;area = (float) Math.sqr t(p*(p-a)*(p -b)*(p-c)); // formula di Erone

}

void calcolaP erimetro(){

perimetro = a + b + c;}

public String toString(){

return "Triangolo ";}

}

A suavolta questaclassepuo esserespecializzatapertipi particolaridi triangoli dove vieneridefinito il metodo perilcalcolodell’area.Quindisi hala classeperi triangoli rettangoli,

Listato 4.6- TriangoloRett.java - definizionedi triangolo rettangolo

package FigureG eometriche;public class Triangol oRett extends Triangolo {

// a e b cateti, c ipotenusa

public Triangol oRett(float c1, float c2){

super(c1,c2, (float)Math. sqrt(c1*c1+c 2*c2)); // costrut tore della supercl asse}

void calcola Area(){

area = (a*b)/2.0f ;}

public String toString(){

return "Triangolo Rett ";}

}

quellaperi triangoli isosceli

40 4. Programmiorientatiagli oggetti.

Listato 4.7- TrinagoloIsoscele.java - definizionedi triangolo isoscele

package FigureGeomet riche;public class Triango loIsoscele extends Triangolo {

// a base, b e c lati uguali

public Triango loIsoscele(f loat base, float lato){

super(base, lato,lato); // costrutto re della superclas se}

void calcolaArea( ){

area = a/2f*(flo at)Math.sqrt (b*b-(a*a)/4 f);}

public String toString(){

return "Triangol oIsoscele ";}

}

equellaperi triangoli equilateri

Listato 4.8- TriangoloEquilatero.java - definizionedi triangolo equilatero

package FigureGeomet riche;public class Triango loEquilatero extends Triangolo {

// a base, b e c lati uguali

public Triango loEquilatero ( float lato){

super(lato, lato,lato); // costrutto re della superclas se}

void calcolaArea( ){

area = a*a*0.433 f; //sqrt(3) /4}

public String toString(){

return "Triangol oEquilatero ";}

}

Altro esempioela classePoligonoReg olare cherappresentai poligoni formati dan lati, ciascunlatodi lunghezzalato .

Listato 4.9- PoligonoRegolare.java - definizionedel poligonoregolare

package FigureGeomet riche;public class Poligon oRegolare extends FiguraGeomet rica {

int nlati; // numero di latifloat lato; // lungheza del lato

public Poligon oRegolare(in t initnlati, float initlato){

4. Programmiorientatiagli oggetti. 41

nlati = initnlati ;lato = initlato;

}

void calcola Area(){

area = lato*lato *nlati/4f/(f loat)Math.ta n(Math.PI/nl ati); // formula di Erone}

void calcolaP erimetro(){

perimetro =nlati * lato;}

public String toString(){

return "PoligonoR egolare ";}

}

Infine la classemain mostraunsempliceusodelleclassidescritteprecedentemente.

Listato 4.10 - Main.java - programma di esempio

import FigureGe ometriche.*;public class Main{

public static void main(String[ ] args){

FiguraGeome trica fig;

fig = new Triangol o(2f,6f,5f);System.out.p rintln(fig+ " " +fig.get Area()+", "+fig.ge tPerimetro() );fig = new Triangol oRett(2f,6f) ;System.out.p rintln(fig+ " " +fig.get Area()+", "+fig.ge tPerimetro() );

fig = new Triangolo Isoscele(2f, 6f);System.out.p rintln(fig+ " " +fig.get Area()+", "+fig.ge tPerimetro() );

fig = new Triangolo Equilatero(6 f);System.out.p rintln(fig+ " " +fig.get Area()+", "+fig.ge tPerimetro() );

fig = new PoligonoR egolare(5,4f );System.out.p rintln(fig+ " " +fig.get Area()+", "+fig.ge tPerimetro() );

}}

Eseguendo taleprogrammasi ottiene:

Triangolo 4.683748 7, 13.0Triangolo Rett 6.0, 14.324555Triangolo Isoscele 5.91608, 14.0Triangolo Equilatero 15.588, 18.0PoligonoR egolare 27.5276 37, 20.0

4.5 Ereditarieta multipla

Il programmapresentato in questasezionemostracomee possibileavere in Java qualcosa simile all’ereditarietamultipla utilizzando le interfacce. Nell’esempio si realizzaun orologio composto da un orologio digitale e da unoanalogico.L’ereditarieta multipla e solo mimatanel sensochevengono forniti solamente i metodi propri di ciascun

42 4. Programmiorientatiagli oggetti.

componente(digitaleo analogico) perla visualizzazionedell’ora dell’orologio, mentre i dati (variabili chememoriz-zanol’ora) sonounici. Diversoapprocciosi dovrebbeadottarenelcasoin cui si vogliaereditaredadiversi oggetti siavariabili chemetodi.

Listato 4.11- DiAnaClock.java - ereditariet a multipla per mezzodell’interfacce.

/*** esempio di eredita rieta’ multipla* mediante uso di interfac ce**/

import java.ut il.*;

/*** classe Clock* definisce i dati relativ i ad un orologio:* ore e minuti*/class Clock{int hours;int minutes;

/*** costruttore* assegna ai due campi l’ora del calcolatore*/Clock(){hours=ne w Date().get Hours();minutes= new Date().g etMinutes();}} // endClass Clock

/*** interfaccia per un orologio digitale**/interfac e DigitalClo ck {void showTime( );}

/*** interfaccia per un orologio analogic o**/interfac e AnalogCloc k {void showTime( );}

/**le classi ADigitalCl ock e AAnalogClock realizzano le due interfacceDefinisc ono un metodo statico di classe per implementare le differen tivisualiz zazioni dell’ora. questo metodo viene chiamato dal metodo che realizzail corrisponde nte metodo dell’in terfaccia associat a.Inoltre il metodo statico puo’ essere attivato da altre classi che voglian o realizzar ela stessa interfacci a. In questo modo vi e’ una sola implement azione dell’inter faccia*/

class ADigital Clock extends Clockimplemen ts DigitalCl ock{

/**metodo statico che implementa la visualizza zione per un orologiodi tipo digitale. stampa le ore ed i minuti separati da :

4. Programmiorientatiagli oggetti. 43

@param cl un oggetto di tipo Clock i cui dati verrano visualizz ati*/public static void classSho wTime(Clock cl){

System. out.println( cl.hours+":" +cl.minutes) ;}

/**realizzaz ione del metodo definito nell’interf acciachiama il metodo statico passando come parametro l’oggett o su cuie’ stato attivato*/public void showTime( ){

classSh owTime(this) ;}

} // endClass ADigita lClock

class AAnalogCl ock extends Clockimplements AnalogC lock{

/**metodo statico che impleme nta la visualizzaz ione per un orologiodi tipo digitale. stampa le ore ed i minuti come linee di *

@param cl un oggetto di tipo Clock i cui dati verrano visualizz ati*/public static void classSho wTime(Clock cl){

int i;System. out.print("h :");for(i=0 ;i<cl.hours; i++)

System.out. print("*");System. out.println( );System. out.print("m :");for(i=0 ;i<cl.minute s;i++)

System.out. print("*");System. out.println( );}

/**realizzaz ione del metodo definito nell’interf acciachiama il metodo statico passando come parametro l’oggett o su cuie’ stato attivato*/public void showTime( ){

classSh owTime(this) ;}

}

/**realizzaz ione di un orologi o digitale-a nalogico*/class DiAnaCloc k extends Clock

impleme nts DigitalC lock,AnalogC lock{

/**relizzazi one del metodo definito per entrambe le interfac cechiama le singole realizzaz ioni, rappresentat e dai metodi statici delleclassi che implementa no le interfacce, passando come parametro l’oggettosu cui e’ stato attivato*/public void showTime( ){ADigitalC lock.classSh owTime(this) ;AAnalogCl ock.classSho wTime(this);}

public static void main(){

44 4. Programmiorientatiagli oggetti.

ADigitalCloc k orologiodi gitale = new ADigitalClo ck();AAnalogClock orologioana logico = new AAnalogCloc k();DiAnaClock orologi o = new DiAnaClock ();

System.out.p rintln("Orol ogio digital e");orologiodigi tale.showTim e();System.out.p rintln("Orol ogio analogi co");orologioanal ogico.showTi me();System.out.p rintln("Orol ogio digital e-analogico" );orologio.sho wTime();}

} // endClass DiAnaClock

Capitolo 5

Programmi ricorsivi.

In questocapitolosi mostracomee possibilerealizzare programmiricorsivi nel linguaggio java.

5.1 Fattoriale

La funzionefattoriale,gia vistanel capitoloprecedente,puo essereespressain termini ricorsivi secondola seguentedefinizione perricorrenza:

åçæuè� í se å è üåêé°å ë í�ïðæ per å�� üIl listato5.1mostraladefinizionedi unaclasseRicfactor ial contenenteduemetodi, entrambi connomericFact ,cheimplementanoin manieraricorsiva il calcolodel fattoriale,unoperdatidi tipo int l’altro perdatiBigInte ger .

Il primo metodo e molto semplice.Seil valore del parametro n e 0 si ritorna il valore1, altrimenti si ritorna ilprodotto tran edil fattorialedi n - 1.

Il secondometodo e simile solochesonostatiutilizzati i metodi definiti nellaclasseBigInte ger pereseguirele operazioni. L’espressione n.multiply (ricFact(n. subtract(bi guno))) ritorna un dato(oggetto)ditipo BigInteger ottenutodallamoltiplicazionedi n conil numeroritornatodall’applicazionedel fattorialestessoadunnumero chee ottenutodallasottrazione di unoan.

Listato 5.1- RicFactorial.java - fattoriale ricorsivo.

// java1.1

import java.ma th.*;

/*** esempi di calcolo del fattori ale con algoritmo ricorsivo.** @author P.Bison Copyrigh t 1997*/

public final class RicFacto rial{

// costanti di tipo BigInte gerstatic final BigInteg er bigzero = new BigInte ger("0");static final BigInteg er biguno = new BigInteg er("1");

// private constructo r// la classe non puo’ essere instanziat aprivate RicFact orial() {}

/*** fattoriale ricorsi vo con risultato e parametro di tipo int.* calcola il fattori ale del numero passato come parametr o. utilizza il tipo int* percui si ha un errato valore di ritorno quando si supera il valore massimo rapprese ntabile* ad esempio il ricFact(15 ) risulta 20043100 16 mentre il risultato corrett o e’ 1307674 368000* risultato e’ corretto fino a Ricfact (12)* @param n valore di cui si deve calcolare il fattoriale

46 5. Programmiricorsivi.

* @return il fattoriale di n*/

public static int ricFact( int n) {

if (n==0) return 1;else return n * ricFact( n-1);}

/*** fattoriale ricorsivo con risultato e parametro di tipo BigInteger .* calcola il fattoriale del numero passato come paramet ro. utilizza il tipo BigInteg er* percui non si ha alcun limite nella rappresenta zione del numero ad esempio si puo’* calcolare il valore BigRicfac t(5000)* @param n valore di cui si deve calcolare il fattorial e* @return il fattoriale di n*/

public static BigInteger ricFact (BigInteger n) {

if (n.equals( bigzero)) return biguno;else return n.multiply(r icFact(n.sub tract(biguno )));

}

public static void main(St ring[] args) {int nint=5;BigInteger nbig = new BigInteg er("500");

System.out.p rintln("ricF act("+nint+" ) = " + ricFact(ni nt));

System.out.p rint("ricFac t("+nbig.toS tring() +") =");BigInteger bignum;bignum = ricFact(n big);System.out.p rintln(bignu m.toString() );}

} // end of class RicFacto rial

Il programmastampalaseguenteuscita,dacuisi vedecheutilizzando il tipoBigIntegersi puocalcolareil fattorialedi 500:

ricFact( 5) = 120ricFact( 500) = 12201368259 911100687012 387854230469 262535743428 03192842192413 588385845373 153881997605 496447502203 281863013616 47714820358416337872 207817720048 078520515932 928547790757 193933060377 29608590862704291745 478824249127 263443056701 732707694610 628023104526 44218878789465754777 149863494367 781037644274 033827365397 471386477878 49543848959553753799 042324106127 132698432774 571554630997 720278101456 10811883737095310163 563244329870 295638966289 116589747695 720879269288 71281780070265174507 768410719624 390394322536 422605234945 850129918571 50124870696156814162 535905669342 381300885624 924689156412 677565448188 65065938479517753608 940057452389 403357984763 639449053130 623237490664 45048824665075946735 862074637925 184200459369 692981022263 971952597190 94521782333175693458 150855233282 076282002340 262690789834 245171200620 77146409794561161276 291459512372 299133401695 523638509428 855920187274 33795173014586357570 828355780158 735432768888 680120399882 384702151467 60544540766353598417 443048012893 831389688163 948746965881 750450692636 53381750554781286400 000000000000 000000000000 000000000000 000000000000 00000000000000000000 000000000000 000000000000 000000000000 000000000000 000000

5.2 Programmi sulle stringhe

I dueprogrammi visti nel capitolo1 cheoperavanosu dati di tipo String vengono qui proposti nella loro versionericorsiva.

5. Programmiricorsivi. 47

Nel casodellaverificaseunastringae palindroma,si e definitoil metodoisPalin conil parametro st chee lastringadaverificare. Sela lunghezzadellastringaeugualea1 (stringaformatadaunsolocarattere)si ritorna il valoretrue poiche talestringae palindroma. Altrimenti si confrontano il primo edultimo caratteree si vede sela stringaottenutatogliendo il primo e l’ultimo caratteree palindroma.

Listato 5.2- RicPalin.java; verifica seuna stringa epalindr oma.

/**** verifica se una stringa e’ palindro ma in maniera ricorsiva** @author P.Bison Copyrig ht 1997**/

public class RicPalin {

public static boolean isPalin(Str ing st) {

if(st.len gth()==1) return true;else return (st.char At(0)==st.ch arAt(st.leng th()-1)) &&

isPalin( st.substring (1,st.length ()-1));}

/*** programma principa le*/

public static void main(String[ ] args) {

for(int i=0; i < args.le ngth; i++){ // itera sul numero di argomen tiSystem.out. print(args[i ]);if (isPalin (args[i])) System. out.println( " e’palindro ma");else System.out.p rintln(" non e’palindrom a");}

}}

Nel casodel Reversesela lunghezzadella stringavale1 si ritorna la stringastessa,altrimenti si concatena allastringaottenutaprendendol’ultimo carattere(st.substr ing(st.leng th()-1) il reversedellastringaottenutadaquelladi partenza togliendo l’ultimo carattere(st.subst ring(0,st.l ength()-1) ).

Listato 5.3- RicReverse.java - capovolge una stringa in maniera ricorsiva.

/**** verifica se una stringa e’ palindro ma in maniera ricorsiva** @author P.Bison Copyrig ht 1997**/

public class RicRever se {

public static String doReverse(St ring st) {

if(st.len gth()==1) return st;else return st.subst ring(st.leng th()-1).conc at(doReverse (st.substrin g(0,st.lengt h()-1)));}

/*** programma principa le*/

public static void main(String[ ] args) {

48 5. Programmiricorsivi.

for(int i=0; i < args.length; i++){ // itera sul numero di argomentiSystem.out .print(args[ i]+" ");System.out .println(doR everse(args[ i]));}

}}

5.3 Anagrammi di una lista

L’anagrammadi unalista e unacombinazionequalunquedegli elementi componentila stringa.Sela stringae com-postoda å elementi,si hannoåçæ possibilicombinazioni. In questasezionesonoriportati dueprogrammicheperme-ttonodi calcolaregli anagrammi di unalista. Il primo (listato5.4)genera e stampatutti gli anagrammi conunasolaattivazione del metodo, mentre nel secondoprogramma(listato5.5) il metodo generaun anagrammadiversoadogniattivazione,finchenonhageneratotutti i possibilianagrammi.

Listato 5.4- SimpleAnag.java - stampadegli anagrammi di una stringa.

/*** stampa degli anagrammi di una stringa** @author P.Bison Copyrig ht 1997**/

public class SimpleA nag{

static int livello ricorsione = -1; /* indica il livello di ricorsione *//**

* costruttore di classe* la classe non puo’ essere instanzia ta*/

private SimpleAnag (){}

public static void calcolaAnag (StringBuff er temp, StringBuf fer anag){

int i, j;StringBuff er subtemp; /* stringa vuota */

livellor icorsione++;

if (temp.l ength () == 1){

anag.setChar At (livellor icorsione, temp.ch arAt (0));System.out.p rintln (anag);

}else

for (i = 0; i < temp.lengt h (); i++){

anag.setCh arAt (livell oricorsione, temp.charAt (i));subtemp = new StringBu ffer ();

/* crea una nuova stringa di n-1 caratte ri senza l’i-esimo carattere */for (j = 0; j < temp.length (); j++)

if (j != i)subtemp.inse rt (subtemp. length (), temp.ch arAt (j));

calcolaAna g (subtemp, anag);}

5. Programmiricorsivi. 49

livellorico rsione--;}

/*** metodo principale*/

public static void main (String []args){

String unaStringa ;String temp;

if (args.le ngth > 0)unaStri nga = args[0];

elseunaStri nga = "AbC";

calcolaAn ag (new StringBuff er (unaStrin ga), new StringBuf fer (unaStri nga));

}} // end of class SimpleA nag

Listato 5.5- Anagrammi.java - generazione di anagrammi.

/*** calcolo degli anagrammi di una stringa** @author P.Bison Copyrigh t 1997**/

public class Anagrammi{

int livellori corsione; /* indica il livello di ricorsi one */int numGenerati; /* numero di anagrammi generati */int numGenerandi; /* numero di anagrammi che si sta generan do */String st; /* stringa di cui si calcola gli anagrammi */StringB uffer anag; /* stringa di lavoro in cui viene generato l’anagramma */

/*** costruttore di classe*/

public Anagrammi (String t){

int i;

livellori corsione = -1;numGenerati = 0; /* nessun anagramma generato */st = t;anag = new StringBuff er (st);

}/*

metodi privati

*/boolean calcolaAnag (StringBuff er temp){

int i, j;StringBuffe r subtemp;

50 5. Programmiricorsivi.

boolean generato = false;

livellor icorsione++;if (temp.l ength () == 1)

{anag.setChar At (livellor icorsione, temp.ch arAt (0));numGenerandi ++;if (numGener andi > numGenerati )

{numGenerati = numGenerandi ;generato = true;

}else

generato = false;}

elsefor (i = 0; i < temp.lengt h (); i++)

{anag.setCh arAt (livell oricorsione, temp.charAt (i));subtemp = new StringBu ffer ();

/* crea una nuova stringa di n-1 caratte ri senza l’i-esimo carattere */for (j = 0; j < temp.length (); j++)

if (j != i)subtemp.inse rt (subtemp. length (), temp.ch arAt (j));

generato = calcolaAnag (subtemp);if (genera to)

break;}

livelloric orsione--;return generato;

}

/*

metodi pubblici

*/

public String getAnagram ma (){

boolean generato ;numGenerandi = 0;generato = calcolaAn ag (new StringBuff er (st));

if (genera to)return anag.toStri ng ();

else{

numGenerati = 0;return "";

}}

/*** metodo principale*/

public static void main (String[]arg s){

Anagrammi unaStringa;String temp;

if (args.l ength > 0)unaStringa = new Anagrammi (args[0]) ;

5. Programmiricorsivi. 51

elseunaStri nga = new Anagrammi ("TaFo");

temp = unaStrin ga.getAnagra mma ();while (temp.lengt h () != 0)

{System. out.println (temp);temp = unaStringa.g etAnagramma ();

}

}

} // end of class Anagrammi

5.4 Torr edi Hanoi

Nel giocodella torredi Hanoi si hanno a disposizione unatavola contre pioli edun certonumero di dischi forati didiametrodifferente. La configurazioneiniziale e formatadatutti i dischicondiametrodecrescenteinfilati in unpiolo.Obiettivo delgiocoemuoveretaletorresuunaltropiolo conle condizioni chesi puo muovereunsolodiscoallavoltae chenessundiscopiu largopuo esseresuunopiu piccolo.

Un semplicealgoritmo ricorsivo puo esseresviluppato considerandochepermuovereunatorredi n dischidaunpiolo adunaltrosi puo, primamuoverela torre formatadaglin-1dischisuperiori sulpiolo nondi arrivo, poi muoverel’unico discorimastosul piolo d’arrivo ed infine muoverela torre di n-1 dischisul piolo finale. Orapermuoverelatorredi n-1 dischisi possonoripetere i medesimi passiconsiderandounatorreformatadan-2 dischi,poi unadan-3dischi,ecosi via finchesi arrivaadunatorreformatadaunsolodiscochesi puo muovereliberamente.

Un quesitocheci si chiede e in quantemossesi muoveunatorredi n dischidaunpiolo adunaltro. Dallastrategiadi giocovisto primasi deducecheil numerodi mossee pari a duevolte il numerodi mossenecessarieperspostarela torre di n-1 dischipiu uno,checorrspondealla mossadi muoverel’ultimo disco. Datochesi conosceil numerodi mossepermuovereunatorreformatadaun solodisco(1 mossa),si puo definirela funzione � é�åúï , cheritornailnumero di mossein funzione di n, conla seguentedefinizione perricorrenza:

� é°åúïêè� í se å è íñ � é�å ë í�ï�� í per å�� í

dacui e possibiledimostrare che � é°åúïêèÁñ���ë í .

Listato 5.6- HanoiTower.java - la torr edi Hanoi.

// java 1.1

import java.mat h.*;

/*** rappresentaz ione della torre di hanoi** @author P.Bison Copyrigh t 1997**/

public class HanoiTow er {static final int maxdisch i = 64;

int ndischi; // numero totale dei dischiint[] numDisc hiPiolo; // dischi per piolo. pioli 0,1 e 2int[][] dischiPiolo ; // lista dei dischi, rappres entati dal loro diametro ,

// present i in ciascun piolo./**

* creazione di una torre content e n dischi sul piolo 0* @param n numero di dischi

52 5. Programmiricorsivi.

*/public HanoiTo wer(int n) {

ndischi = n;

numDischiPio lo = new int[3];numDischiPio lo[0]=n;numDischiPio lo[1]=numDis chiPiolo[2]= 0;

dischiPiolo = new int[3][n];

for(int i =0;i<n;i ++) dischiPi olo[0][i]=n- i; // inserimento dischi nel piolo 0for(int i =0;i<n;i ++) dischiPi olo[1][i]=di schiPiolo[2] [i]=0;

}

// metodi

/*** muove tutti i dischi dal piolo 0 al piolo 2*/

public void esegui() {muoviTorre(n dischi,0,2,1 );

}

/*** muove ndischi da un piolo ad un altro usando il terzo* come piolo d’appoggio* @param ndischi il numero di dischi da muovere* @param da piolo in cui vi sono i dischi* @param a piolo dove portare i dischi* @param usando piolo d’appoggi o*/

public void muoviTor re(int ndischi, int da, int a, int usando) {

if(ndischi > 0) {muoviTorre (ndischi-1,d a,usando,a);muoviDisco (da,a);muoviTorre (ndischi-1,u sando,a,da);

}}

/*** muove un disco da un piolo ad un altro* @param da piolo da cui prendere il disco* @param a piolo dove portare il disco*/

public void muoviDis co(int da, int a) {

numDischiPio lo[da] -= 1;dischiPiolo[ a][numDischi Piolo[a]]=di schiPiolo[da ][numDischiP iolo[da]];dischiPiolo[ da][numDisch iPiolo[da]] = 0;numDischiPio lo[a] += 1;

System.out.p rintln(da + " -> " + a);stampaConfig ();

}

/*** visualizza la configura zione della torre*/

public void stampaCo nfig() {int riga,nsp azi,nstar,pi olo;int i,j;

5. Programmiricorsivi. 53

// stampa indici di piolofor(j=0 ;j<3;j++) {

for(i=0;i<n dischi;i++) System.out.p rint(" ");System.out. print(j);for(i=0;i<n dischi;i++) System.out.p rint(" ");}

System. out.println( );

// stampa i dischifor(rig a=1;riga<=nd ischi;riga++ ) {

for(piolo=0 ;piolo<3;pio lo++) {nstar = dischiP iolo[piolo][ ndischi-riga ];nspazi = ndischi - nstar;for(i=0;i <nspazi;i++) System.out. print(" ");for(i=0;i <nstar;i++) System.out.p rint("*");System.ou t.print("|") ;for(i=0;i <nstar;i++) System.out.p rint("*");for(i=0;i <nspazi;i++) System.out. print(" ");}

System.out. println();}

}

/*** calcola il numero di mosse necessari o a muovere una* torre complete*/

public BigInteg er numeromosse(){

// chiama calcolamoss e convertend o il il valore del campo ndischi// a valore di tipo BigInte ger

return calcola mosse(new BigInteg er(String.va lueOf(ndisch i)));}

static final BigInteg er biguno = new BigInteg er("1");static final BigInteg er bigdue = new BigInteg er("2");BigIntege r calcolamos se(BigIntege r bign){

if (bign.equa ls(biguno)) return biguno;else return bigdue. multiply(cal colamosse(bi gn.subtract( biguno))).ad d(biguno);

}

/*** metodo principale*/

public static void main(Str ing[] args){HanoiTo wer torre;int ndisk;

if (args.leng th > 0)ndisk = Integer.v alueOf(args[ 0],10).intVa lue();

elsendisk=3;

torre = new HanoiTo wer(ndisk);torre.e segui();System. out.print("N umero di mosse: ");System. out.println( torre.numero mosse());

// calcolo numero mosse per una torre di 64 elementiSystem. out.print("N umero di mosse per 64 elementi : ");System. out.println( (new HanoiTo wer(64)).num eromosse());

}

54 5. Programmiricorsivi.

} // end of class HanoiTow er

Attivandoil programmasenzaalcunargomento,si ottienela seguente uscita:

0 -> 20 1 2| | |

**|** | |***|*** | *|*0 -> 1

0 1 2| | || | |

***|*** **|** *|*2 -> 1

0 1 2| | || *|* |

***|*** **|** |0 -> 2

0 1 2| | || *|* || **|** ***|***

1 -> 00 1 2| | || | |

*|* **|** ***|***1 -> 2

0 1 2| | || | **|**

*|* | ***|***0 -> 2

0 1 2| | *|*| | **|**| | ***|***

Numero di mosse: 7Numero di mosse per 64 elementi: 18446744073 709551615

5.5 Fai da te

1. Nel casodel calcolo degli anagrammi definito nella classeAnagrammi per calcolareun nuovo anagrammasi devono trovare tutti quelli precedenti. Si modifichi il programma in manieratale chenon si abbiaquestainefficienza,ovverochenonsi debbaognivoltacalcolaretutti gli anagrammi precedenti.

2. Si sviluppi unprogrammacherisolvail problemadelleottoregine. Suunascacchiera8x8sideveposzionareottoreginein manierataleche,secondole regoledelgiocodegli scacchi,nessunareginapossamangiareun’altra. Siestendaancheal casodi N reginein unascacchieraNxN.

Capitolo 6

Ricerca edordinamento

6.1 Ricercasu array

Listato 6.1- SearchArra y.java - ricercasu array di interi.

public class SearchAr ray {/*

* private constructo r. non si puo’ istanziar e\*/

private SearchA rray(){}

/*** ricerca lineare. dati un array di interi ed un valore* ritorna l’indice della locazio ne in cui si trova* tale valore. Ritorna -1 se non esiste.*/

public static int linearS earch(int[] a,int value){

int i;

for(i=0;i<a .length;i++)if(value= =a[i]) break; // esci dal ciclo se trovato

if (i==a.le ngth) return -1;else return i;

}

/*** ricerca binaria. dati un array ordinato decresce nte di interi ed un valore* ritorna l’indice della locazio ne in cui si trova* tale valore. Ritorna -1 se non esiste.*/

public static int binaryS earch(int[] a,int value){

int i,j,k;

i=-1; j=0; k=a.length-1 ;while (j<=k){

i=(j+k)/2;if(value== a[i]) break; // esci dal ciclo se trovatoelse

if (value<a[i] ) k=i-1;else j=i+1;

}if (j>k) return -1;

56 6. Ricercaedordinamento.

else return i;}

public static void main (String[]arg s){

int[] a ={ 2, -8, 23, 90, 33, 25, 37, 89, -45, 27};int[] b ={ -45, -8, 2, 23, 25, 27, 33, 37, 89, 90};

System.out .println(a);System.out .println(lin earSearch(a, 33));System.out .println(lin earSearch(a, 100));System.out .println(bin arySearch(b, 33));System.out .println(bin arySearch(b, 100));

}}

6.2 Ordinamento di array

Listato 6.2- SortArra y.java - ordinamento di un array di interi.

public class SortArr ay {/*

* private construct or. non si puo’ istanzia re\*/

private SortArray(){ }

/*ordinam ento lineare /selezione

questo metodo e’ basato sul seguente principio :

1. seleziona l’elemento con la chiave piu’ piccola2. scambialo con il primo elemento a1

quindi si ripete queste operazi oni con i rimanent i n-1 elementi,poi con n-2, finche’ rimane solamente un elemento , il piu’ grande.

*/public static void linearS ort(int[] dati)

{int i,j,k;int min;int x;

for (i=0;i<dati. length-1;i++ ) {

// ricerca minimok=i;min=dati[ i];for (j=i+1;j<da ti.length;j+ +)

if (dati[j] < min) {k=j;min=dati[j] ;}

// esegui lo scambiox = dati[k];dati[k] = dati[i];dati[i] = x;}

6. Ricercaedordinamento. 57

}

/*ordinam ento per inserimen to/tabellare

gli elementi da ordinare sono concettu almente divisi in una sequenzadi destinazion e Ai... Ai-1 e una sequenza d’ingres so A1 ... An

Ad ogni passo, partendo da i=2 ed incrementa ndo i di uno, il i-esimo elementodella sequenza d’ingresso viene messo nella sequenza di destinazioneinserend olo nel posto appropriat o.

Per trovare il posto d’inserimen to, si alterna tra test e spostament i, cioe’si compare x con Aj e o si inserisce x oppure si muove Aj a destra e siprocede verso sinistra. Vi sono due distinte condizioni che causano la finedi questo ciclo :1. si e’ trovato un elemento Aj con una chiave minore della chiave di X2. si e’ raggiunto l’eleme nto piu’ a sinistr a nella sequenza di destinazio ne

*/public static void insertSort(i nt[] dati){

int i,j;int x;

for (i=1;i< dati.length; i++) {x = dati[i];j = i-1;while (j>=0 && x < dati[j]) {

dati[j+ 1] = dati[j] ;j = j-1;}

dati[j+1] = x;}

}

/*ordiname nto per scambio diretto( bubble sort)

compara ed eventualm ente scambia coppie adiacentifinche’ tutti gli elementi sono ordinati

*/public static void bubbleSo rt(int dati[])

{int i,j;int x;

for(i=1;i<d ati.length-1 ;i++)for(j=dat i.length-1;j >=i;j--)

if (dati[j-1] > dati[j]){x = dati[j- 1]; dati[j-1 ]=dati[j]; dati[j] = x;}

}

/*ordiname nto per scambio (shake sort)

simile al bubblesortsi alternano passate dal basso verso l’alto con passate dall’al to verso il basso

*/public static void shakeSor t(int[] dati){

int j,k,sup ,inf;

58 6. Ricercaedordinamento.

int x;

sup=1; inf=k=dat i.length-1;

do {// passata dal basso verso l’altofor(j=in f;j>=sup;j-- )if (dati[j-1] > dati[j]){

x = dati[j-1 ]; dati[j-1] =dati[j]; dati[j] = x;k=j;}

sup = k+1;// passata dall’alto verso il bassofor(j=su p;j<=inf;j++ )if (dati[j-1] > dati[j]){

x = dati[j-1 ]; dati[j-1] =dati[j]; dati[j] = x;k=j;}

inf = k-1;} while(sup<=i nf);

}

/*ordinam ento per partizion e (quick sort)

*/public static void quickSo rt(int[] dati){

partitionSor t(dati,0,dat i.length-1);}

static void partitio nSort(int[] dati, int l,int r){

int i,j;int med; // valore medianoint temp;

i=l; j=r;med = dati[(l+r) / 2];do {

while (dati[i] < med) i = i+1;while (dati[j] > med) j = j-1;if (i<=j) {

temp = dati[i]; dati[i]= dati[j]; dati[j]=t emp;i = i+1; j = j-1;}

} while(i<=j);if (l<j) partiti onSort(dati, l,j);if (i<r) partiti onSort(dati, i,r);

}

public static void stampa( int[] a){

for(int i=0;i<a.le ngth;i++)System.out .print(a[i]+ ", ");

System.out.p rintln();}

public static void copia(i nt[] a,int[] b){

for(int i=0;i<a.le ngth;i++)

6. Ricercaedordinamento. 59

a[i]=b[i];}

public static void main (String []args){

int[] a ={ 5, -8, 23, 90, 33, 25, 37, 89, -45, 27};int[] b = new int[a.len gth];

stampa(a);copia(b,a); linearSort(b ); stampa(b) ;copia(b,a); insertSort( b); stampa( b);copia(b,a); bubbleSort( b); stampa(b );copia(b,a); shakeSort(b ); stampa(b) ;copia(b,a); quickSort(b ); stampa(b) ;

}}

6.3 Ordinamento di array generico

Listato 6.3- SortAbstract.java - ordinamento di array generico.

abstract class Data{abstract boolean gt(Data dato);abstract void print() ;}

class DataInt extends Data {int key;int info;

DataInt( int k,int i){

key=k;info=i;}

boolean gt(Data dato){DataInt altroda to = (DataIn t) dato;return (key>alt rodato.key);}

void print(){System.ou t.println(ke y+" "+info);}

}

class DataStrin g extends Data {String key;String info;

DataStri ng(String k,String i){

key=k;info=i;}

boolean gt(Data dato){DataStrin g altrodato = (DataStrin g) dato;return (key.com pareTo(altro dato.key)>0) ;

60 6. Ricercaedordinamento.

}

void print(){System.o ut.println(k ey+" "+info) ;}

}

public class SortAbs tract{

int numDati=0;Data[] dati;

public SortAbs tract(int n){dati = new Data[n];}

public void insert(D ata dato){dati[num Dati]=dato;numDati= numDati+1;}

public void linearS ort(){

int i,j,k;Data min,temp;

for (i=0;i<numDa ti;i++) {

// ricerca minimok=i;min=dati[ i];for (j=i+1;j<nu mDati;j++)

if (min.gt(da ti[j])) {k=j;min=dati[j] ;}

// esegui lo scambiotemp = dati[k]; dati[k] = dati[i] ; dati[i] = temp;}

}

public void print(){

for(int i=0;i<numDat i;i++) dati[i].pri nt();System.o ut.println() ;}

public static void main(St ring[] argv){int i,j;SortAbst ract daint = new SortAbs tract(10);SortAbst ract dastr = new SortAbs tract(10);

// inserisce i numeri da 100 a 1for(i=0, j=100;i<10;i ++,j--) daint.inse rt(new DataInt(j,3 *j));daint.pr int();daint.li nearSort();daint.pr int();

for(i=0, j=99;i<10;i+ +,j--) dastr.inser t(new DataString(" ABC"+j,"Info "+3*j));dastr.pr int();

6. Ricercaedordinamento. 61

dastr.lin earSort();dastr.pri nt();}}

62 6. Ricercaedordinamento.

Capitolo 7

Struttur e dinamiche

7.1 Liste su interi

7.1.1 Nododella lista

Listato 7.1- Nodo.java - definizionedi elementodella lista

public class Nodo {Nodo next;int valore;

Nodo(in t val){

valore=val; next=null;}

public int getValor e(){

return valore;}

public Nodo getNext (){

return next;}

public void setNext (Nodo nuovo){

next = nuovo;}

}

7.1.2 Lista FirstInFirstOut

Listato 7.2- FIFOint.j ava - lista First In First Out

public class FIFOint {Nodo primo;

public FIFOint(){

primo=null;}

64 7. Strutturedinamiche.

public void inserisci(in t valore){

Nodo nuovo,ultim o;

nuovo = new Nodo(valor e);if (primo == null) primo = nuovo;else { // ricerca fine della lista

ultimo=p rimo;while (ultimo. getNext() != null) ultimo =ultimo.ge tNext();ultimo.s etNext(nuovo );}

}

public int preleva (){

int val=0;

if (primo==null ) throw new IllegalAcces sError("coda vuota");val = primo.get Valore();primo = primo.g etNext();return val;

}

public static void main(String [] args){

FIFOint lista=n ew FIFOint() ;

lista.ins erisci(10);lista.ins erisci(20);lista.ins erisci(30);System.ou t.println(li sta.preleva( ));System.ou t.println(li sta.preleva( ));System.ou t.println(li sta.preleva( ));System.ou t.println(li sta.preleva( ));

}}

7.1.3 Lista FirstInFirstOut ottimizzata

Listato 7.3- FIFOintO pt.java - lista First In First Out ottimizzata

public class FIFOint Opt extends FIFOint {Nodo ultimo;

public FIFOintOpt( ){

super();ultimo=nul l;

}

public void inserisci(in t valore){

Nodo nuovo;

nuovo = new Nodo(valor e);if (primo == null) primo = nuovo;else ultimo.setN ext(nuovo);ultimo = nuovo;

}

public int preleva ()

7. Strutturedinamiche. 65

{int val;

val = super.prel eva();if (primo == null) ultimo = null;return val;

}

public static void main(String[ ] args){

FIFOintOpt lista=new FIFOint Opt();

lista.inse risci(10);lista.inse risci(20);lista.inse risci(30);System.out .println(lis ta.preleva() );System.out .println(lis ta.preleva() );System.out .println(lis ta.preleva() );System.out .println(lis ta.preleva() );

}}

7.1.4 Lista LastInFirstOut

Listato 7.4- LIFOint.ja va - lista Last In First Out

public class LIFOint extends FIFOint{

public void inseris ci(int valore){

Nodo nuovo;

nuovo = new Nodo(valore );nuovo.setNe xt(primo);primo = nuovo;

}

public static void main(String[ ] args){

LIFOint lista=ne w LIFOint();

lista.inse risci(10);lista.inse risci(20);lista.inse risci(30);System.out .println(lis ta.preleva() );System.out .println(lis ta.preleva() );System.out .println(lis ta.preleva() );System.out .println(lis ta.preleva() );

}}

66 7. Strutturedinamiche.

Capitolo 8

Files e Input/Output.

8.1 Gestionedei file.

Listato 8.1- FileTest.java: gestionedel file systemesterno.

/**esempio di utilizzo della classe File per la gestione dei file esterni

il programma verifica la presenza di una directory. Se e’ presente la cancellacon i file in essa contenut i, altriment i crea tale directory con dieci file erinomina uno dei file o con un metodo diretto o con una copia e cancellazio neAll’inizi o stampa i valori di alcune propriet a’ del sistema.

*/import java.io. *;

class FileTest {

/**genera la copia di un file

*/static void copyFile( File from, File to){int ch;

try {FileInput Stream ffrom = new FileInputSt ream(from);FileOutpu tStream fto = new FileOutputSt ream(to);

while ((ch = ffrom.re ad())!=-1) fto.wri te(ch);ffrom.clo se();fto.close ();} catch (IOExce ption e){

System.o ut.println(" error in copy"+e);}

}

public static void main(){File fdir;File fdat;FileOutpu tStream fout;String[] filelist;

// stampa alcune proprieta’ del sistemaSystem.ou t.println("f ile.separato r: "+System. getProperty( "file.separa tor"));System.ou t.println("j ava.version: "+System.ge tProperty("j ava.version" ));System.ou t.println("p ath.separato r: "+System. getProperty( "path.separa tor"));System.ou t.println("u ser.name: "+System .getProperty ("user.name" ));System.ou t.println("u ser.home: "+System .getProperty ("user.home" ));

68 8. Filese Input/Output.

System.o ut.println(" user.dir: "+System .getProperty ("user.dir") );

// file � dir1 nella directo ry correntefdir= new File(Syste m.getPropert y("user.dir" ),"dir1");

// vede se la dir1 esisteif(fdir. exists()){

// cancellaz ione della directo ry// non viene cancellata se contiene dei file

if(!fdir. delete()){// lista i file contenuti nella directoryfilelis t = fdir.lis t();

// ciclo di cancell azione dei filefor(int i=0;i<filel ist.length;i ++) {

System.out. println("del eting "+filelist[i ]);// creazione di un oggetto File associato all’i-esimo nome

fdat = new File(fdir,fi lelist[i]);fdat.delete (); // cancellazio ne del file}

fdir.del ete(); // cancella zione della directory}

}

else {// crea directorySystem.o ut.println(" created dir: "+fdir.mkdi r());

// creazione di dieci file nella directoryfor(int i=0;i<10;i ++) {

// creazio ne di un oggetto File per indicare il nome e pathfdat = new File(fdir," data"+i);try{

fout = new FileOutpu tStream(fdat );fout.clo se();} catch (IOException e) {

System.out.p rintln(fdat. getName()+" IOException" + e);}

// rename del file data0 in data99if(i==0) {

File newfile = new File(fdir," data99");fdat = new File(fd ir,"data0");if(fdat.rena meTo(newfile ))

System.ou t.println("f ile renamed" );else {

FileTest. copyFile(fda t,newfile);fdat.delet e();System.out .println("fi le copied");

}}

}}}}

8.2 Lettura file di tipo ASCII.

Listato 8.2- AsciiReader.java: lettura file ASCII.

/**classe che implement a

8. Filese Input/Output. 69

*/import java.io. *;

class AsciiRead er extends FilterI nputStream{int ch=’ ’;char nlchar=’\n ’;

AsciiRea der(InputStr eam in){super(in );nlchar = System.getP roperty("lin e.separator" ).charAt(0);

}

public String readStr ing()throws IOExcep tion{StringBu ffer temp= new StringBuf fer();

while (ch!=-1 && (ch == ’ ’ || ch == nlchar)) ch=read() ; // salta spazi

if (ch==-1) return(nu ll);temp.appe nd((char)ch) ;while ((ch=read ())!=-1 && ch != ’ ’ && ch!=nlchar) temp.append( (char)ch); // salta spazireturn temp.toS tring();}

public int readInt() throws IOException {//String st =this.rea dString();//System. out.println( "’"+st+"’");//return 0;return Integer. parseInt(thi s.readString ());}

public static void main(){String st;try {AsciiRead er ar = new AsciiReader( new FileInpu tStream("tes t"));while((st =ar.readStri ng())!=null) {

System.o ut.print(st) ;System.o ut.print(ar. readInt());System.o ut.println() ;

}} catch (IOExce ption e) {}}}

8.3 Lettura medianteStreamTokenizer.

Listato 8.3- TokenTest.java: usodel StreamTokenizer.

/**Esempio d’uso della classe StreamTokeni zer*/import java.io. *;

class TokenTest{

public static final char strDelimiter = ’"’;

public static void main (String argv[]){

70 8. Filese Input/Output.

try{

Reader r = new BufferedRea der (new FileReade r ("test"));StreamTo kenizer st = new StreamT okenizer (r);

st.quoteChar (strDelimit er); // definis ce carattere delimitator e delle stringhe

st.commentCh ar (’#’); // definsc e carattere per commentare singole linee

while (st.next Token () != StreamTokeni zer.TT_EOF){

switch (st.ttype ){case StreamTok enizer.TT_WO RD:

System.out.p rintln ("Word: " + st.sval);break;case StreamT okenizer.TT_ NUMBER:System.out.p rintln ("Number: " + st.nval);break;case strDeli miter:System.out.p rintln ("String: " + st.sval);break;default:System.out.p rintln ("Special char: " + (char) st.ttype );

}

}}catch (IOExcepti on e){}

}}

8.4 Ar chiviazionein formato ZIP.

Listato 8.4- Zip.java: generazionedi un archivio.

/**

Zip

memorizz a tutto il contenu to della directory di lavoro, comprese le sottodirect ory.

java Zip [nome_archi vio]

se non e’ presente il nome_archi vio salva in archive.zip

*/import java.io . *;import java.ut il. *;import java.ut il.zip. *;

class Zip{

static byte[] buffer = new byte[1024 ];static String sep;

8. Filese Input/Output. 71

static byte lsep;

static void storeEn try (ZipOutp utStream zipf, InputStre am entryfile )throws Exception{

int len;

while ((len = entryfile .read (buffer)) != -1)zipf.wr ite (buffer, 0, len);

entryfile .close ();}

static void storeDi r (ZipOutput Stream zipf, String[]fil elist, String path)throws Exception{

int i;File fin;

String[] subfilelist;ZipEntry entry;String fname;

for (i = 0; i < filelis t.length; i++){

if (filelist[ i].equalsIgn oreCase ("ZipStore "))continue;

fname = path + filelist[i ];System. out.println (fname);fin = new File (fname);if (fin.isDir ectory ())

{entry = new ZipEntry (fname + sep);zipf.putN extEntry (entry);zipf.clos eEntry ();subfileli st = fin.lis t ();storeDir (zipf, subfilelist , path + filelist[ i] + sep);

}else

{entry = new ZipEntry (fname);zipf.putN extEntry (entry);storeEntr y (zipf, new FileInputSt ream (fin));zipf.clos eEntry ();

}}

}

public static void main (String argv[]){

File fdir;File fdat;

String[] filelist;ZipOutputSt ream zipf;String actualdir;String zipname = "archive.zip ";int i;

for (i = 0; i < argv.le ngth; i++){

zipname = argv[i] ;}

fdat = new File (zipnam e);

72 8. Filese Input/Output.

if (fdat.e xists ())fdat.del ete ();

actualdir = System.get Property ("user.di r");System.out .println ("actual directory: " + actualdir );sep = System.get Property ("file.se parator");System.out .println ("file.se parator: " + sep);lsep = (byte) System.g etProperty ("line. separator"). charAt (0);System.out .println ("line.se parator: " + lsep);

try{

fdir = new File (System.ge tProperty ("user.d ir"));filelist = fdir.list ();zipf = new ZipOutput Stream (new FileOutputSt ream (zipnam e));storeDir (zipf, filelist, "");zipf.clo se ();

}catch (Exception e){

System.o ut.println ("Entry Exception " + e);}System.out .println("DO NE");

}}

Listato 8.5- UnZip.java: estrazione di un archivio.

/**

UnZip

programm a per unzippare un archivio

unzip [-x] [nome_arc hivio]

se presente il flag -x estrae i file dall’ar chivio,altrimen ti visulaizz a solamente la lista di tali file

se e’ presente nome_archiv io opera su tale archivi o,segnalan do errore nel caso non esistes se,altrimen ti opera su tutti gli eventual i file con estensi one .zipche si trovano nella directory di lavoro

converte fine linea dei file di testo individuati analiizandoil primo buffer letto

converte inoltre il separtore usato nei pathname

*/import java.io . *;import java.ut il. *;import java.ut il.zip. *;

class UnZip{

8. Filese Input/Output. 73

static byte[] buffer = new byte[1024] ;static String fsep;static byte lsep;

/**analizza il buffer per vedere se di tipo textritorna falso se vi sono caratter i <32 e non sono\n, \t \r \f*/

static boolean isText (int len){

if (len<=0) return false;for (int i=0;i<le n;i++)

if ((buffe r[i]<32)&&!( (buffer[i]== (byte)’\n’)| |(buffer[i]= =(byte)’\t’) ||(buffer[i ]==(byte)’\r ’)||(buffer[ i]==(byte)’\ f’))) return false;

return true;}

static void saveEnt ry (InputStr eam entryfil e, FileOutpu tStream fout)throws Exception{

int len;boolean textfil e;

len = entryfile .read (buffer);if (textfile = isText(len))

System.o ut.print(" (text)" );

while (len != -1){

if (textfile)for (int i = 0; i < len; i++)

if ((buffer[i] == 13) || (buffer[ i] == 10))buffer[ i] = lsep;

fout.wr ite (buffer, 0, len);len = entryfile .read (buffer);

}fout.close ();

entryfile .close ();}

public static void main (String argv[]){

File fdir;File fdat;

String[] filelist;String[] zipfiles;

ZipFile zipf = null;String zipname = null;String topdir;Enumeration listentry;ZipEntry entry;String entryname;int i;int zipidx;boolean extract = false;

// analizza argomentifor (i = 0; i < argv.le ngth; i++)

74 8. Filese Input/Output.

{if (argv[i]. compareTo ("-x") == 0)

extract = true;else

zipname = argv[i];}

// estrae proprieta del sistemafsep = System.ge tProperty ("file.s eparator");System.out .println ("file.se parator: " + fsep);lsep = (byte) System.g etProperty ("line. separator"). charAt (0);System.out .println ("line.se parator: " + lsep);topdir = System. getProperty ("user.dir") ;System.out .println ("actual directory: " + topdir);

if (zipnam e != null){

zipfiles = new String[1] ;zipfiles[0] = zipname;

}else

{fdir = new File (topdir) ;zipfiles = fdir.li st ();

}

for (zipidx = 0; zipidx < zipfiles .length; zipidx++)if (zipfiles[z ipidx].endsW ith (".zip") )

{System.out .println ();System.out .println ("Zip file: " + zipfiles[zi pidx]);try{

zipf = new ZipFile (zipfil es[zipidx]);}catch (Exception e){

System.o ut.println ("Excep tion " + e);System.e xit (1);

}

listentry = zipf.entri es ();

while (listentry .hasMoreElem ents ()){

entry = (ZipEntry) listentry.n extElement ();entryname = entry.getNam e ();entryname = entryname.re place (’\\’, ’/’);entryname = entryname.re place (’\\’, fsep.charAt (0));

System.out.p rint ("Entry : " + entryname);if (extract)

try{

fdat = new File (entryname );

if (entry.isDi rectory ())fdir = fdat;

else if (fdat.getPar ent () != null)fdir = new File (fdat.ge tParent ());

elsefdir = null;

if ((fdir != null) && (!fdir.exi sts ()))

8. Filese Input/Output. 75

fdir.mk dirs ();if (!entry.isDi rectory ())

{saveEntry (zipf.g etInputStrea m (entry), new FileOutpu tStream (fdat));

}}

catch (Except ion e){

System.out. println ("Entry Exceptio n " + e);continue;

}System.ou t.println();

}}

System.out. println ("DONE");}

}

76 8. Filese Input/Output.

AppendiceA

Prestazioni

Usualmenteil codicegeneratodauncompilatoreJavavieneeseguitodauninterpretesoftwarecherealizzala macchinavirtualeperil linguaggio Java. Peraumentarel’efficienzadell’esecuzionesi possono seguire duestrade:

� compilatori JITi compilatori Just-In-Time vengono utilizzati dalla macchina virtuale per compilare al volo duranteil carica-mentoil codicejava nel linguaggiomacchina delcalcolatore sucui funzionala macchinavirtuale

� chipsJavaquesti chipssonodellecpucheesegueno il codicejava

Un sempliceprogrammache permettedi analizzarele prestazioni ottenibili utilizzando il linguaggio Java, emostratonel seguentelistato:

Listato A.1 - Benchmark.java - programma di test in Java

/*** implementa la classe Benchmark che definis ce un insieme di* algoritmi di benchmark** @author P.Bison Copyrigh t 1997*/

public class Benchmar k{// intTest constants

public static final int INT_LOOP = 2000000;// floattest constant s

public static final float CONST1= 3.141597 E0f;public static final float CONST2= 1.783903 2e4f;public static final int FLOAT_LOOP = 4000000;

// fiboTest constantspublic static final int FIBO_LOOP = 100;public static final int FIBO_NUM = 24;

// sieveTest constant spublic static final int SIEVE_SIZE = 8190;public static final int SIEVE_LOOP = 1000;

// savageTest constan tspublic static final int SAVAGE_LOOP = 200000;

/*** test delle quattro operazioni sugli interi*/

public static long intTest (){

long i=10000 , iter;

78 A. Prestazioni.

for (iter = 1; iter <= INT_LOOP; iter++){

i = -3 + (5 * i) / 5 + 3;

}return i;

}

/*** test sulle quattro operazioni sui reali (float)*/

public static float floatTest (){

float a=0f, b=0f, c=0f, d=0f;int i;

for (i = 1; i <= FLOAT_LOOP; ++i){

a = CONST1* CONST2* (float)i ;b = CONST1 / CONST2 / (float)i ;c = CONST1+ CONST2+ (float)i ;d = CONST1- CONST2- (float)i ;

}return a+b+c+d;}

/*** calcolo di numeri primi con il crivello di Erastotene*/

public static boolean sieveTes t (){

int i, prime, k, count, iter;boolean[ ] flags = new boolean[SI EVE_SIZE + 1];

for (iter = 1; iter <= SIEVE_LOOP; iter++){

count = 0;for (i = 0; i <= SIEVE_SIZE; i++)

flags[i] = true;for (i = 0; i <= SIEVE_SIZE; i++)

{if (flags[i])

{prime = i + i + 3;for (k = i + prime; k <= SIEVE_SIZ E; k += prime)

flags[k] = false;count++;

}}

}return flags[SIEV E_SIZE];

}

/*** calcolo dei numeri di Fibonac ci in maniera ricorsiva*/

public static long fib (long n){

if (n > 2)

A. Prestazioni. 79

return (fib (n - 1) + fib (n - 2));else

return (1);}

public static long fiboTest (long n){

long ris = 0;int i;for (i = 1; i <= FIBO_LOOP; i++)

{ris = fib (n);

}return ris;

}

/** test funzion i trigonomet riche*/

public static double savageTest (){

int i;double a;

a = 1.0;for (i = 1; i <= SAVAGE_LOOP;i++)

a = Math.tan (Math.atan (Math.e xp (Math.log (Math.sqrt (a * a)))));return a;

}

public static void main (String []args){

long t1, t0, maint0, maint1;long a;float b;long c;boolean d;double e;

maint0 = System.curre ntTimeMillis ();System.ou t.println ("Java Benchmarks");System.ou t.println ();

System.ou t.println ("Intege r");t0 = System.cur rentTimeMill is ();a=intTest ();t1 = System.cur rentTimeMill is ();System.ou t.println (a);System.ou t.println ("Time: " + (t1 - t0) + " millisec.");System.ou t.println ();

System.ou t.println ("Float" );t0 = System.cur rentTimeMill is ();b=floatTe st ();t1 = System.cur rentTimeMill is ();System.ou t.println (b);System.ou t.println ("Time: " + (t1 - t0) + " millisec.");System.ou t.println ();

System.ou t.println ("Fibona cci");t0 = System.cur rentTimeMill is ();c = fiboTest (FIBO_NUM);

80 A. Prestazioni.

t1 = System.cu rrentTimeMil lis ();System.o ut.println (c);System.o ut.println ("Time: " + (t1 - t0) + " millisec.") ;System.o ut.println ();

System.o ut.println ("Sieve ");t0 = System.cu rrentTimeMil lis ();d=sieveT est ();t1 = System.cu rrentTimeMil lis ();System.o ut.println (d);System.o ut.println ("Time: " + (t1 - t0) + " millisec.") ;System.o ut.println ();

System.o ut.println ("Savag e");t0 = System.cu rrentTimeMil lis ();e = savageTest ();t1 = System.cu rrentTimeMil lis ();System.o ut.println (e);System.o ut.println ("Time: " + (t1 - t0) + " millisec.") ;System.o ut.println ();maint1 = System.curr entTimeMilli s ();System.o ut.println ("Total time: " + (maint1 - maint0) + " millisec. ");

}

}// end of class Benchmark

Il programmaimplementacinquetests:

� calcolosuvalori interi

� calcolosuvalori reali

� attivazionedi metodo/proceduraattraversol’esecuzionedellafunzione peril calcolodeinumeri di Fibonacci

� il crivello di Erastotene

� calcolodi funzioni trascendenti

ecalcolai tempidi esecuzionedeisingoli teste delprogrammacomplessivo.Il corrispondente programmain C e:

Listato A.2 - Benchmark.c- programma di test in C

/**

*/#include <stdio.h>#include <time.h>

#define TRUE 1#define FALSE 0

#define INT_LOOP 2000000

#define CONST13.141597E0#define CONST21.7839032e4#define FLOAT_LOOP4000000

#define FIBO_LOOP 100#define FIBO_NUM 24

#define SIEVE_SIZE 8190

A. Prestazioni. 81

#define SIEVE_LOOP 1000

#define SAVAGE_LOOP 200000

longintTest (){

long i = 10000, iter;

for (iter = 1; iter <= INT_LOOP; iter++){

i = -3 + (5 * i) / 5 + 3;

}return i;

}

/*** test sulle quattro operazioni sui reali (float)*/

floatfloatTest (){

float a=0.0, b=0.0, c=0.0, d=0.0;int i;

for (i = 1; i <= FLOAT_LOOP; ++i){

a = CONST1* CONST2* (float)i;b = CONST1 / CONST2 / (float)i;c = CONST1+ CONST2+ (float)i;d = CONST1- CONST2- (float)i;

}return a+b+c+d;}

longfib (long x){

if (x > 2)return (fib (x - 1) + fib (x - 2));

elsereturn (1);

}

longfiboTest (long n){

long ris;int i;for (i = 1; i <= FIBO_LOOP; i++)

{ris = fib (n);

}return ris;

}

charsieveTest (){

int i, prime, k, count, iter;

82 A. Prestazioni.

char flags[S IEVE_SIZE + 1] ={0};

for (iter = 1; iter <= SIEVE_LOOP; iter++){

count = 0;for (i = 0; i <= SIEVE_SIZ E; i++)

flags[i] = TRUE;for (i = 0; i <= SIEVE_SIZ E; i++)

{if (flags[ i])

{prime = i + i + 3;for (k = i + prime; k <= SIEVE_SIZE; k += prime)

flags[k] = FALSE;count++;

}}

}return flags[SIEVE_ SIZE];

}

extern double tan (), atan (), exp (), log (), sqrt ();

doublesavageTe st (){

int i;double a;

a = 1.0;for (i = 1; i <= SAVAGE_LOOP; i++)

a = tan (atan (exp (log (sqrt (a * a)))));

return (a);}

intmain (){

clock_t start, stop, mainstart , mainstop;long a;float b;long c;char d;double e;

mainstart = clock ();printf ("C benchmark\n\n");printf ("Integer\n ");start = clock ();a=intTest ();stop = clock ();printf ("%d\nTime: %d millisec \n\n",a, (int) (((float) (stop - start)) / CLOCKS_PER_SEC * 1000.0));

printf ("Float\n") ;start = clock ();b=floatTest ();stop = clock ();printf ("%e\nTime: %d millisec \n\n", b,(int) (((float) (stop - start)) / CLOCKS_PER_SEC * 1000.0));

A. Prestazioni. 83

printf ("Fibonacci\ n");start = clock ();c = fiboTest (FIBO_NUM);stop = clock ();printf ("%d\nTime: %d millisec\ n\n", c, (int) (((float) (stop - start)) / CLOCKS_PER_SEC * 1000.0));

printf ("Sieve\n");start = clock ();d=sieve Test ();stop = clock ();printf ("%d\nTime: %d millisec\ n\n",d, (int) (((float) (stop - start)) / CLOCKS_PER_SEC * 1000.0) );

printf ("Savage\n") ;start = clock ();e = savageTes t ();stop = clock ();printf ("%f\nTime: %d millisec\ n\n", e, (int) (((float) (stop - start)) / CLOCKS_PER_SEC * 1000.0));mainsto p = clock ();printf ("Total time: %d millise c\n", (int) (((float) (mainsto p - mainstar t)) / CLOCKS_PER_SEC * 1000.0) );

return (0);

}

I tempi di esecuzione, espressiin millisecondi, riportati in tabellasonorelativi ad unaworkstation SunULTRA1creator. Per la compilazione ed esecuzione del programmaJava si e utilizzato il packageSolari SPARC EditionJDK/JIT v1.1.3coni comandi

javac Benchmar k.javajava Benchmark

mentreperil programmaC il compilatoreGNU gccversione2.7.1coni comandi:

gcc -o Benchmark Benchmar k.cBenchmark

Nel casodelprogrammaJavavengonoriportati i tempisiaconil compilatoreJust-In-Timechesenza.

test Java Cw JIT w/o JIT

Integer 1551 4689 170Float 1887 8438 2119Fibonacci 1836 11840 1669Sieve 2326 29897 4219Savage 1144 1652 1029Totale 8782 56540 9210

Comesipuonotaredallatabella,utilizzandouncompilatoreJust-in-Timesi haunnotevoleaumentodelleprestazioni.Nel particolarecasodi questoprogrammasi eottenutaunadiminuzionedel tempodi esecuzioneperognisingolotest,chenelcasodel crivello di Erastotene(Sieve) e parial 92%.

Confrontando conil programmaC si notache,nelcasoJTC,tretest(Float,Fibonacci, Savage)vengonoeseguiti intempiparagonabili, mentregli altri duesonocontradditori. Nel casoInteger il programmain C surclassal’equivalenteJavaessendoquest’ultimo9.12 voltepiu lento.D’altro cantoil programmaJavahaprestazioni migliori nelcasoSievein cui e1.81voltepiu veloce.

Ovviamentequestoesempioda solounastimaparzialedelle effettive prestazioni.Innumerevoli fattori possonoconcorrerealla determinazionedei tempidi esecuzione(efficienzadel compilatore, caricodellamacchina) percui sidevono utilizzaretestpiu complessisesi vuole avereunquadropiu completo.

84 A. Prestazioni.

AppendiceB

Risorseal Ladseb

In questaappendicevengonoelencatile risorsedisponibili localmenteperla programmazionein Java

B.1 Macintosh

Peril Macintoshsonodisponibili:

MRJ 2.x sistemaruntime perJava e disponibile nell’ultima releasedelsistemaoperativo (8.1)

MRJ SDK 2.x sistemadi sviluppoperJava comprendenteil compilatore

tutoria l1.1 un tutorial on line in formatoHTML

Questerisorsesonodisponibili la prima nel CDrom del sistemaoperativo, le altre comefile .seanel folder Java inPublic.

B.2 Sun450

Il softwareper lo sviluppo e’ installatoin /opt/java /jdkx.x dove x.x e la versione. Perutilizzarlo si devemetternellapropria pathla directory /opt/java/j dkx.x/bin .E possibileleggere la documentazione aprendoconnetscape(la versione3 si trova in /usr/local/ netscape ) ilfile /opt/jav a/jdk1.1.6 /docs/index .html .E presenteancheil tutorial in /opt/java /tutorial .

86 B. Risorseal Ladseb.

Bibliografia

[1] K.Arnold, J.Gosling.TheJavaTM ProgrammingLanguage. Addison-Wesley, Reading,Massachuttes,1996.

[2] J.Gosling,B.Joy, G.Steele.TheJavaTM LanguageSpecification. Addison-Wesley, Reading, Massachuttes,1996.

[3] T.Lindholm,F.Yellin. TheJavaTM Virtual MachineSpecification. Addison-Wesley, Reading, Massachuttes,1996.

[4] J.Gosling,F.Yellin, TheJava team.TheJavaTM Application ProgrammingInterface, Volume1. Addison-Wesley,Reading,Massachuttes,1996.

[5] J.Gosling,F.Yellin, TheJava team.TheJavaTM Application ProgrammingInterface, Volume2. Addison-Wesley,Reading,Massachuttes,1996.

[6] M.Campione, K.Walrath . The JavaTM Tutorial. Addison-Wesley, Reading, Massachuttes, 1996.(http:/ /java.sun. com/tutoria l/ )

87

Indice dellefigure

1.1 Rappresentazionedi unoggetto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Scambiodi unmessaggio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Alberodi ereditarieta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.4 Grafodi ereditarieta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

89

Indice dei listati

TypeCast.java: conversionedi tipi esplicita. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Niente.java - programmaminimoin Java. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17SciavoVostro.java - semplicestampa.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17Eco.java - stampadegli argomenti. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18Palin.java- verificaseunastringaepalindroma. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19Reverse.java - capovolgeunastringa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19Factorial.java - fattorialeiterativo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20MCD.java - MassimoComunDivisore. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21Sieve.java - il crivello di Erastotene. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22Div50.java - calcolodelladivisioneesatta.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23Factorial.java - classeFactorialconoverloadingdeimetodi. . . . . . . . . . . . . . . . . . . . . . . . . . . 26

Complex.java - rappresentazionedei numeri complessi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29SimpleMatrix.java - rappresentazionedi matriciNxM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32MagicSquare.java- rappresentazione delquadratomagico. . . . . . . . . . . . . . . . . . . . . . . . . . . 35FiguraGeometrica.java - unaclasseastratta. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38Triangolo.java- definizionedi triangolo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38TriangoloRett.java - definizione di triangolo rettangolo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39TrinagoloIsoscele.java - definizione di triangolo isoscele . . . . . . . . . . . . . . . . . . . . . . . . . . . 39TriangoloEquilatero.java - definizionedi triangoloequilatero . . . . . . . . . . . . . . . . . . . . . . . . . 40PoligonoRegolare.java - definizione delpoligonoregolare . . . . . . . . . . . . . . . . . . . . . . . . . . . 40Main.java - programmadi esempio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41DiAnaClock.java - ereditarieta multiplapermezzodell’interfacce. . . . . . . . . . . . . . . . . . . . . . . 42

RicFactorial.java - fattorialericorsivo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45RicPalin.java;verificaseunastringaepalindroma. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47RicReverse.java - capovolgeunastringain maniera ricorsiva. . . . . . . . . . . . . . . . . . . . . . . . . . 47SimpleAnag.java - stampadegli anagrammidi unastringa. . . . . . . . . . . . . . . . . . . . . . . . . . . 48Anagrammi.java- generazionedi anagrammi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49HanoiTower.java - la torredi Hanoi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

SearchArray.java - ricercasuarraydi interi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55SortArray.java- ordinamentodi unarraydi interi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56SortAbstract.java - ordinamentodi arraygenerico. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Nodo.java - definizionedi elemento dellalista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63FIFOint.java- lista First In First Out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63FIFOintOpt.java - lista First In First Out ottimizzata. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64LIFOint.java - lista LastIn First Out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

FileTest.java: gestionedel file systemesterno.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67AsciiReader.java: letturafile ASCII. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68TokenTest.java: usodelStreamTokenizer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69Zip.java: generazionedi unarchivio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70UnZip.java: estrazionedi unarchivio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Benchmark.java- programmadi testin Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77Benchmark.c- programmadi testin C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

91