8 - Stringhe
e altre classi dalla Libreria Standard (Java API)
Programmazione e analisi di dati Modulo A: Programmazione in Java
Paolo Milazzo
Dipartimento di Informatica, Universit`a di Pisa http://pages.di.unipi.it/milazzo
milazzo di.unipi.it
Corso di Laurea Magistrale in Informatica Umanistica A.A. 2018/2019
Introduzione
Abbiamo visto come creare classi che includono metodi diversi In particolare, metodi ausiliari che risolvono sottoproblemi Vedremo pi`u avanti (nella seconda parte del corso) come realizzare programmi che consistono di pi`u classi che si dividono il lavoro
I metodi di una classe potranno invocare i metodi di un’altra Per il momentovediamo come utilizare classi gi`a fatte
LaLibreria Standarddi Java
I Java API(Application Programming Interface) Una enorme collezione di classi gi`a implementate!
La Libreria Standard di Java (1)
Le classi della Libreria Standard sono organizzate inpacchetti tematici. Ad esempio:
java.lang contiene le classi pi`u comunemente utilizzate (considerate
“di base” per il linguaggio)
java.util contiene classi di utilit`a (strutture dati, data/ora, ....) java.io contiene classi per l’input/output (tramite console, files, ....) java.awt e java.swing contengono classi per costruire interfacce grafiche
java.security contiene classi per crittografia e altri aspetti di sicurezza
...
La Libreria Standard di Java (2)
Le classi del pacchetto java.lang sono immediatamente disponibili al programmatore
Le classi degli altri pacchetti devono essereimportate all’inzio del programma:
i m p o r t j a v a . u t i l . S c a n n e r ; // I m p o r t a la c l a s s e S c a n n e r
i m p o r t j a v a . u t i l .*; // I m p o r t a t u t t e le c l a s s i del p a c c h e t t o j a v a . u t i l
All’interno del proprio codice, un metodo di un’altra classe si invoca cos`ı:
<nomeclasse>.<nomemetodo>(<parametri>)
La Libreria Standard di Java (3)
La documentazione ufficialedella Libreria Standard di Java `e disponibile qui:
http://docs.oracle.com/javase/8/docs/api/
Trovate un link nella pagina web del corso USATE QUESTA DOCUMENTAZIONE!!!
ContieneTUTTE le informazioni necessarie di TUTTE le classi E’ navigabile per singolo pacchetto, per singola classe e singolo metodo...
ATTENZIONE: dalla versione 9 di Java ipacchetti di sono ulteriormente raggruppati in moduli. Se consultate la documentazione della versione 9 (o supertiori) le classi a cui faremo riferimento le trovate nel modulo java.base.
La classe Math
Esempio: la classe Math
contiene numerosi metodi che eseguono calcoli matematici Alcuni tra i metodi pi`u comuni della classe Math
Math.abs(a) restituisce il valore assoluto del numero a Math.pow(a,b) restituisce l’elevamento a potenza ab Math.sqrt(a) restituisce la radice quadrata di a
Math.round(a) restituisce l’arrotondamento di a all’intero pi`u vicino Math.floor(a) restituisce l’arrotondamento di a per difetto
Math.ceil(a) restituisce l’arrotondamento di a per eccesso Math.sin(a) restituisce il seno di a
Math.random() restituisce un numero frazionario casuale compreso tra 0.0 (compreso) e 1.0 (escluso). Esiste anche la classe Random che fa cose pi`u sofisticate...)
...
Esempio di uso
// g e n e r a un n u m e r o c a s u a l e tra 0.0 e 1.0 d o u b l e n u m e r o C a s u a l e = M a t h . r a n d o m ();
// lo t r a s f o r m a in un n u m e r o tra 0.0 e 1 0 . 0 n u m e r o C a s u a l e *= 10;
// lo t r a s f o r m a in un n u m e r o tra 1.0 e 1 0 . 0 s e n z a d e c i m a l i d o u b l e i n t e r o C a s u a l e = M a t h . c e i l ( n u m e r o C a s u a l e );
// ne c a l c o l a il q u a d r a t o
int q u a d r a t o = (int) M a t h . pow ( i n t e r o C a s u a l e , 2 ) ;
Oggetti
Moltissime delle classi della Libreria Standard si usano per creareoggetti Questa `e la caratteristica principale di Java (e di tutti gli altri linguaggi di programmazioneorientati agli oggetti)
Un oggetto `e una istanza di una classe:
un oggetto pu`o possedere un propriostato interno
la classe specifica i metodiche possono essere invocati sull’oggetto (metodi d’istanza, specificano il comportamento dell’oggetto) La relazione tra classi e oggetti `e la seguente:
Unaclassedefinisce un tipo (non primitivo) i cui valori sono oggetti
La classe String (1)
Esempio: la classe String
contiene metodi per l’elaborazione di stringhe Creare oggetti di tipo String
S t r i n g n o m e = new S t r i n g (" M a r i o ");
S t r i n g c o g n o m e = new S t r i n g (" R o s s i ");
Le variabili nome e cognome
sono due oggetti di tipo String sono due istanze della classe String
hanno stati interni diversi ("Mario" e "Rossi");
Per creare un oggetto si usa la parola chiave new
new `e seguito dalla chiamata a uncostruttore della classe: uno speciale metodo che ha lo stesso nome della classe e inizializza il nuovo oggetto
La classe String (2)
La classe String in realt`a `e speciale. I suoi oggetti possono essere creati anche cos`ı:
S t r i n g n o m e = " M a r i o "; // e q u i v a l e n t e a new S t r i n g (" M a r i o ");
S t r i n g c o g n o m e = " R o s s i "; // e q u i v a l e n t e a new S t r i n g (" R o s s i ");
Le variabili di tipo String possono essere usate come tutte le altre variabili. Ad esempio:
S t r i n g p r i m o n o m e = n o m e ; // in a s s e g a m e n t i S y s t e m . out . p r i n t l n ( c o g n o m e ); // s t a m p a t e
m e t o d o A u s i l i a r i o ( nome , c o g n o m e ); // n e l l e c h i a m a t e a m e t o d i a u s i l i a r i
La classe String (3)
La classe String mette a disposizione numerosi metodi per elaborare i propri oggetti
La chiamata di un metodo su un oggettoha la seguente sintassi:
<nomeoggetto>.<nomemetodo>(<parametri>)
La classe String (4)
Supponendo che str sia un oggetto di tipo String, ecco alcuni tra i metodi pi`u comuni che si possono chiamare su esso:
str.length() restituisce la lunghezza della stringa (numero di caratteri)
str.isEmpty() restituisce true se la stringa `e vuota (0 caratteri) o false altrimenti
str.substring(i,j) restituisce la porzione di str che va dal carattere in posizione i al carattere in posizione j (escluso).
str.substring(i) restituisce la porzione di str che va dal carattere in posizione i alla fine della stringa.
ATTENZIONE A substring si inizia a contare da 0, quindi:
S t r i n g s a l u t o = " Hello , W o r l d ! ";
S y s t e m . out . p r i n t l n ( s a l u t o . s u b s t r i n g ( 7 , 1 2 ) ) ; // s t a m p a W o r l d
i e j devono essere minori di String.length()
La classe String (5)
Un esempio: stampa un parola tre caratteri per volta
p u b l i c c l a s s P a r o l a S p e z z e t t a t a {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { // p a r o l a da s p e z z e t t a r e
S t r i n g p a r o l a = " S u p e r c a l i f r a g i l i s t i c h e s p i r a l i d o s o !! ";
// s c a n d i s c e la s t r i n g a 3 c a r a t t e r i per v o l t a for (int i =0; i < p a r o l a . l e n g t h (); i + = 3 ) {
/* a s s i c u r a che la p o r z i o n e c o n s i d e r a t a ( da i a i +3) non s u p e r i la f i n e d e l l a s t r i n g a */
if ( i +3 < p a r o l a . l e n g t h ())
S y s t e m . out . p r i n t l n ( p a r o l a . s u b s t r i n g ( i , i + 3 ) ) ; e l s e
S y s t e m . out . p r i n t l n ( p a r o l a . s u b s t r i n g ( i , p a r o l a . l e n g t h ( ) ) ) ; }
} }
Il tipo primitivo char
Quando si elaborano stringhe spesso si deve lavorare con i singoli caratteri.
Tra itipi primitivi di Java, il tipo char descrive valori che sono singoli caratteri
Codifica Unicode: rivedere la lezione sui tipi primitivi...
I letterali di tipo carattere si descrivono tra singoli apici
’a’, ’b’, ’c’, ’1’, ’2’, ’[’, ’]’, ’_’, ’ ’, ....
caratteri speciali: ’\n’ (a capo) e altri poco usati...
Un esempio di assegnamento:
c h a r c a r a t t e r e = ’ a ’;
I valori di tipo char sono in realt`a codificati come interi (Unicode), quindi si possono applicare operatori aritmetici:
c a r a t t e r e ++; // " i n c r e m e n t a " di 1 il c a r a t t e r e S y s t e m . out . p r i n t l n ( c a r a t t e r e ); // s t a m p a b
Switch su char
Il tipo char pu`o essere usato anche nell’ambito di uno switch
c h a r s c e l t a = ’ d ’;
s w i t c h ( s c e l t a ) {
c a s e ’ a ’: S y s t e m . out . p r i n t l n (" Hai s c e l t o a "); b r e a k; c a s e ’ b ’: S y s t e m . out . p r i n t l n (" Hai s c e l t o b "); b r e a k; c a s e ’ c ’: S y s t e m . out . p r i n t l n (" Hai s c e l t o c "); b r e a k; c a s e ’ d ’: S y s t e m . out . p r i n t l n (" Hai s c e l t o d "); b r e a k; c a s e ’ e ’: S y s t e m . out . p r i n t l n (" Hai s c e l t o e "); b r e a k; d e f a u l t: S y s t e m . out . p r i n t l n (" L e t t e r a s b a g l i a t a ");
}
Altri metodi di String (1)
Altri metodi utili per gli oggetti di tipo String (in cui c `e, ad esempio, una variabile di tipo char)
str.charAt(i) restituisce il carattere della stringa in posizione i.
Analogo a str.substring(i,i+1), ma il risultato `e di tipo char anzich´e String
str.indexOf(c) restituisce la posizione della prima occorrenza del carattere c nella stringa str oppure -1 se non presente
str.indexOf(c,i) restituisce la posizione della prima occorrenza successiva a i del carattere c nella stringa str oppure -1 se non presente
Altri metodi di String (2)
Esempio: stampa un carattere ogni tre
p u b l i c c l a s s U n o O g n i T r e {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { // p a r o l a da s t a m p a r e
S t r i n g p a r o l a = " S u p e r c a l i f r a g i l i s t i c h e s p i r a l i d o s o !! ";
// s c a n d i s c e la s t r i n g a 3 c a r a t t e r i per v o l t a for (int i =0; i < p a r o l a . l e n g t h (); i + = 3 ) {
S y s t e m . out . p r i n t l n ( p a r o l a . c h a r A t ( i ));
} } }
Esempio: in che posizione `e la h?
S t r i n g p a r o l a = " S u p e r c a l i f r a g i l i s t i c h e s p i r a l i d o s o !! ";
S y s t e m . out . p r i n t l n ( p a r o l a . i n d e x O f (’ h ’)); // s t a m p a 20
Esempio d’uso
Conta i caratteri di spazio in un testo
i m p o r t j a v a . u t i l . S c a n n e r ; p u b l i c c l a s s C o n t a S p a z i {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { S c a n n e r i n p u t = new S c a n n e r ( S y s t e m . in );
S y s t e m . out . p r i n t l n (" I n s e r i s c i una r i g a di t e s t o ");
S t r i n g s = i n p u t . n e x t L i n e ();
int c o n t =0; // c o n t a t o r e d e g l i s p a z i
int i = s . i n d e x O f (’ ’); // i n d i c e u s a t o per s c a n d i r e il t e s t o if ( i != -1) c o n t ++;
w h i l e ( i != -1) {
// c e r c a il p r o s s i m o s p a z i o a p a r t i r e d a l l a p o s i z i o n e i +1 i = s . i n d e x O f (’ ’, i + 1 ) ;
if ( i != -1) c o n t ++;
}
S y s t e m . out . p r i n t l n ( c o n t );
} }
Concatenazione di stringhe (1)
La concatenazionedi due stringhe "Mario" e "Rossi" `e semplicemente la stringa "MarioRossi"
L’operatore di concatenazione in Java si scrive semplicemente +
S t r i n g n o m e = " P a o l o ";
S t r i n g c o g n o m e = " M i l a z z o ";
S y s t e m . out . p r i n t l n ( n o m e + c o g n o m e ); // s t a m p a P a o l o M i l a z z o S y s t e m . out . p r i n t l n ( n o m e +" "+ c o g n o m e ); // s t a m p a P a o l o M i l a z z o
L’operatore + in Java `e sovraccaricatodi significati (overloaded): pu`o essere applicato sia a numeri che a stringhe
Che cosa succede se mischiamo numeri e stringhe in una espressione?
S y s t e m . out . p r i n t l n (" Rai " + 3); // s t a m p a R a i 3 S y s t e m . out . p r i n t l n (3 + 4 + 5); // s t a m p a 12 S y s t e m . out . p r i n t l n (" " + 3 + 4 + 5); // s t a m p a 345 S y s t e m . out . p r i n t l n (4 + 5 + " p i p p o "); // s t a m p a 9 p i p p o
Concatenazione di stringhe (2)
La concatenazione `e molto utile per ridurreil numero degli enunciati System.out.print(...)
Per esempio possiamo combinare :
// s t a m p a Il r i s u l t a t o e ’:
S y s t e m . out . p r i n t (" Il r i s u l t a t o e ’: ");
// s t a m p a il v a l o r e di ris s u l l a s t e s s a r i g a e va a c a p o S y s t e m . out . p r i n t l n ( ris );
nella singola invocazione:
S y s t e m . out . p r i n t l n (" Il r i s u l t a t o e ’: " + ris );
Convertire numeri in stringhe e viceversa
Per convertire unnumero intero i (o double d) in unastringa:
Integer.toString(i) (oppure Double.toString(d)) i+"" (oppure d+"") (concatenazione con stringa vuota)
Per convertire unastringa s che rappresenta un numeroin un int (o double)
Integer.parseInt(s) (oppure Double.parseDouble(s)) Esempi:
int a n n o = 2 0 1 3 ;
S t r i n g a n n o T e s t o = a n n o ; // E R R O R E : t i p i i n c o m p a t i b i l i S t r i n g a n n o T e s t o = " " + a n n o ; // OK
d o u b l e pi = " 3 . 1 4 1 5 9 2 6 "; // E R R O R E : t i p i i n c o m p a t i b i l i d o u b l e pi = D o u b l e . p a r s e D o u b l e (" 3 . 1 4 1 5 9 2 6 "); // OK
int m i l i a r d o = I n t e g e r . p a r s e I n t (" 1 0 0 0 0 0 0 0 0 0 "); // OK
Nota: anche Integer e Double sono classi della Java API
Input di stringhe (1)
Per chiedere all’utente di inserire una stringa si possono usare due metodi di Scanner (oggetto input)
input.next() legge una singola parola
input.nextLine() legge un’intera riga (tutti i caratteri fino al ritorno a capo)
S t r i n g s1 , s2 , s3 ;
S y s t e m . out . p r i n t l n (" I n s e r i s c i due r i g h e di t e s t o ");
s1 = i n p u t . n e x t L i n e ();
s2 = i n p u t . n e x t ();
s3 = i n p u t . n e x t L i n e ();
S y s t e m . out . p r i n t l n (" s1 - - " + s1 );
S y s t e m . out . p r i n t l n (" s2 - - " + s2 );
S y s t e m . out . p r i n t l n (" s3 - - " + s3 );
Esecuzione:
I n s e r i s c i due r i g h e di t e s t o e c c o la p r i m a r i g a
e c c o la s e c o n d a r i g a s1 - - e c c o la p r i m a r i g a s2 - - e c c o
s3 - - la s e c o n d a r i g a
Input di stringhe (2)
Il metodo next() viene solitamente usato anche per leggere singoli caratteri, come segue:
S y s t e m . out . p r i n t l n (" V u o i c o n t i n u a r e ? [ S / N ] ");
// l e g g e il p r i m o c a r a t t e r e d e l l a p r o s s i m a p a r o l a c h a r s c e l t a = i n p u t . n e x t (). c h a r A t ( 0 ) ;
s w i t c h ( s c e l t a ) {
c a s e ’ S ’: S y s t e m . out . p r i n t l n (" c o n t i n u a "); b r e a k;
c a s e ’ N ’: S y s t e m . out . p r i n t l n (" b a s t a "); b r e a k; d e f a u l t: S y s t e m . out . p r i n t l n (" E R R O R E ");
}
Esempio di esecuzione
V u o i c o n t i n u a r e ? [ S / N ] N
b a s t a
ma in realt`a succede anche quanto segue
V u o i c o n t i n u a r e ? [ S / N ] N O O O O ! ! ! !
b a s t a
Input di stringhe (3)
Il metodo nextLine() ha un problemanoto Consideriamo la seguente porzione di programma:
int n = i n p u t . n e x t I n t ();
S t r i n g s1 = i n p u t . n e x t L i n e ();
S t r i n g s2 = i n p u t . n e x t L i n e ();
CASO 1. Supponiamo che l’utente voglia inserire il seguente input:
44 g a t t i in f i l a per 3
Abbiamo
n diventa 44
s1 diventa " gatti in"
s2 diventa "fila per 3"
Input di stringhe (4)
Consideriamo sempre la stessa porzione di programma:
int n = i n p u t . n e x t I n t ();
S t r i n g s1 = i n p u t . n e x t L i n e ();
S t r i n g s2 = i n p u t . n e x t L i n e ();
CASO 2. Supponiamo che l’utente voglia inserire il seguente input:
44 g a t t i in f i l a per 3
Abbiamo
n diventa 44 s1 diventa ""
s2 diventa "gatti in"
Il metodo nextLine() ha letto la stringa vuota tra 44 e il ritorno a capo della prima riga
Non c’e’ una soluzione generale a questo problema... bisogna tenerne conto quando si usano questi metodi...
Confronto tra stringhe (1)
Per dire se due stringhe sono uguali non si pu`o usare ==
questo vale in generale per tutti gli oggetti
== confronterebbe l’indirizzo di memoria dei due oggetti...
La classe String fornisce metodi per confrontare stringhe
s1.equals(s2) restituisce true se s1 e s2 sono uguali (stessa sequenza di caratteri), e false altrimenti
s1.compareTo(s2) restituisce
I un valoreminore di 0se s1 precede s2 lessicograficamente
I un valoremaggiore di 0se s2 precede s1lessicograficamente
I il valore0 se s1 e s2 sono uguali
L’ordine lessicografico`e simile all’ordine alfabetico, con la differenza che nessun simbolo `e ignorato (spazi, accenti, apostrofi, ecc...)
Confronto tra stringhe (2)
Esempio (NOTA: Questo `e unottimo esempio su come si fanno i cicli!!!):
i m p o r t j a v a . u t i l . S c a n n e r ; p u b l i c c l a s s I n d o v i n a P a r o l a {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { S c a n n e r i n p u t = new S c a n n e r ( S y s t e m . in );
S t r i n g p a r o l a M i s t e r i o s a = " c i a o ";
int t e n t a t i v i =0; // c o n t a t o r e dei t e n t a t i v i
b o o l e a n i n d o v i n a t o =f a l s e; // " f l a g " che d i c e q u a n d o t e r m i n a r e do {
S t r i n g s = i n p u t . n e x t ();
if ( s . e q u a l s ( p a r o l a M i s t e r i o s a )) { S y s t e m . out . p r i n t l n (" I N D O V I N A T O !!! ");
i n d o v i n a t o =t r u e; // i n t e r r o m p e il c i c l o } e l s e {
S y s t e m . out . p r i n t l n (" S b a g l i a t o ... ");
t e n t a t i v i ++;
if ( p a r o l a M i s t e r i o s a . c o m p a r e T o ( s ) <0)
S y s t e m . out . p r i n t l n (" La p a r o l a m i s t e r i o s a p r e c e d e " + s );
e l s e
S y s t e m . out . p r i n t l n (" La p a r o l a m i s t e r i o s a s e g u e " + s );
}
} w h i l e (! i n d o v i n a t o && t e n t a t i v i < 1 0 ) ; // due c o n d i z i o n i di u s c i t a !!
// v e r i f i c a il m o t i v o d e l l ’ u s c i t a dal c i c l o
if (! i n d o v i n a t o ) S y s t e m . out . p r i n t l n (" T e n t a t i v i e s a u r i t i ");
} }