Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays
Mutability Lo stato di un oggetto immutabile non cambia mai Ex: BankAccount e’ modificabile Array e’ mutabile String e’ immutabile
String Una stringa e’ una sequenza di caratteri (anche vuota) In Java sono oggetti della classe String una volta creati il loro contenuto non può essere modificato non avremo a disposizione metodi per modificare tale oggetto ma solo per leggerlo o per leggerne alcune sue parti
String Per creare un oggetto di tipo String non abbiamo bisogno di invocare il metodo new. Si possono dichiarare variabili di classe String e assegnare loro stringhe arbitrarie. La variabile s contiene il valore, ovvero il riferimento all’oggetto che contiene la sequenza di caratteri String s=“ Hello World!”; s="" ; // stringa vuota
Principali operazioni La classe String definisce vari metodi d'istanza utili (riferiamo ai manuali) Lunghezza di una stringa: String hello = "Hello, World!"; int lung = hello.length();
Concatenazione String nome = "Mario"; String cognome = "Rossi"; System.out.println(nome + cognome); //stampa MarioRossi
Confronto Attenzione: come per tutti gli oggetti e’ possibile usare gli operatori == e != per confrontare stringhe E’ poco utile perche’ confronta il riferimento non il loro contenuto Vorremmo invece sapere se 1. Sono uguali? Cioè, sono la stessa sequenza di caratteri? 2. Quale delle due stringhe viene prima in ordine lessicografico?
Equals s1.equals(s2) restituisce un valore di tipo boolean: -true se s1 e s2 sono uguali come sequenze di caratteri -false altrimenti String s1 = "Ciao"; String s2 = "Ciao"; boolean b = s1.equals(s2); \\ b vale true boolean c = (s1 == s2); \\ c vale false
CompareTo s1.compareTo(s2) restituisce un valore di tipo int: * un valore minore di 0 se s1 precede s2 lessicograficamente, * un valore maggiore di 0 se s2 precede s1, * il valore 0 se sono uguali. b = "cargo".compareTo("cathode") < 0; \\ b vale true
Arrays Oggetti mutabili Gli array sono sequenze di variabili indirizzabili con indici interi: sono composti da elementi omogenei (tutti dello stesso tipo) ogni elemento è identificato all'interno dell'array da un numero d'ordine detto indice dell'elemento il numero di elementi dell'array è detto lunghezza (o dimensione) dell'array
Creazione [] = new [ ]; * è il tipo degli elementi * è la variabile di tipo array * è la dimensione (fissa)
Esempio int[] list = new int[5]; // array di interi di dimensione 5 Bankaccount[] list = new Bankaccount[5]; // array di oggetti BankAccount di dimensione 5
Accesso agli elementi Per riferire i singoli elementi di un array si usano le parentesi quadre: [ ] La dimensione di un array si determina usando:.length
In alternativa L’array puo’ anche essere inizializzato indicando i valori esplicitamente char[] vocali = {'a', 'e', 'i', 'o', 'u'};
In alternativa L’array puo’ anche essere inizializzato indicando i valori esplicitamente char[] vocali = {'a', 'e', 'i', 'o', 'u'};
public class ProcArrays{ //OVERVIEW: la classe fornisce procedure utili per // manipolare arrays di interi public static int cerca(int [] a,int x){ \\EFFECTS: restituisce il numero di occorrenze di x in a int occ=0; for (int i = 0; i< a.length ; i++) {if (a[i]==x) {occ=occ+1;} } return occ; } public static boolean incr(int [] a){ \\EFFECTS:restituisce true se a e’ ordinato in modo crescente int prev; for (int i = 1; i< a.length ; i++) {prev=a[i-1]; if (prev> a[i]) { return false;} } return true;} }
Esercizio Implementare il seguente metodo statico public static boolean multiples(int [] a, int x){ \\MODIFIES:a \\EFFECTS: modifica a, moltiplicando ogni valore per x } Passaggio dei parametri: l’array con cui viene chiamato il metodo viene modificato, perche’ il riferimento e’ condiviso
Specifica: commenti informali E’ utile descrivere i metodi statici tramite commenti informali che descrivono il loro comportamento (vedremo che questa sara’ la specifica, ed avra’ un ruolo fondamentale) (1) precondizione (REQUIRES): vincoli sugli input (2) postcondizione (EFFECTS): cosa fa (3) eventuali modifiche (MODIFIES): tutto quello che puo’ essere modificato
public static int [] append(int [] a, int [] b){ \\REQUIRES: a,b diversi da null \\EFFECTS: restituisce un array che e’ la concatenazione di a e b, ESEMPIO: a=[3,2,6], b[9]====> ab=[3,2,6,9]} Se MODIFIES non e’ presente: non devono essere modificati gli argomenti (attenzione al passaggio dei parametri!) REQUIRES: garantisce che non siano null
Esercizi public static int cercaord(int [] a,int x){ \\REQUIRES: a non e’ null ed e’ ordinato in ordine crescente \\EFFECTS: restituisce il numero di occorrenze di x in a (eventualmente 0)} REQUIRES (pre-condizione) impone vincoli sull’input Possono essere implementati nello stesso modo (il metodo che funziona per quelli non ordinati funziona anche per quelli ordinati (non vice-versa) Ma sfruttando l’ordinamento si ottiene una soluzione piu’ efficiente (va sfruttata la precondizione)
public static boolean subset(int [] a,int [] b){ \\REQUIRES\\REQUIRES: a e b diversi da null \\EFFECTS:restituisce true se a e’ un sottoinsieme di b \\false altrimenti} Esempio: a=[4,3] b=[3,1,4,3] SI a=[4,3] b=[3,8,1] NO tutti gli elementi di a compaiono in b
Oggetti Servono per definire nuovi tipi di dato collezioni di dati + relative operazioni Daremo la specifica di un semplice tipo di dato astratto (descrizione dello stato e delle operazioni) La specifica descrive la classe: intestazione dei metodi d’istanza e dei costruttori con i relativi commenti, e la descrizione degli oggetti astratti
public class Libro{ //OVERVIEW: un Libro memorizza il titolo (String), //l’autore (String), numero di copie (int) public Libro(String t,String a,int n){ //REQUIRES: n >0, t,a diversi da null //EFFECTS: crea un nuovo Libro con titolo t, //autore a, e numero di copie n } public void somma(int num) { //REQUIRES: num>0 //MODIFIES:this //EFFECTS: aggiorna il numero delle copie sommando //num } public String autore(){ //EFFECTS: restituisce l’autore di this} public String titolo(){ //EFFECTS: restituisce il titolo di this}
public int copie(){ //EFFECTS: restituisce il numero di copie di this} public boolean equals(Libro p){ //REQUIRES: p non e’ null //EFFECTS: restituisce true se this e p // sono uguali, altrimenti false} } Dare l’implementazione usando variabili d’istanza private Partire dallo stato degli oggetti Poi implementare il costruttore ed i metodi di conseguenza
Esercizio: Part II Vogliamo realizzare un modulo che usa il tipo di dato Libro Un insieme di metodi statici che effettuano operazioni su un insieme di Libri (rappresentati come un array di Libro)--biblioteca Vediamo la specifica della classe (da implementare)
public class ProcLibro{ //OVERVIEW: definisce metodi statici per //effettuare operazioni su un array di Libri public static boolean cerca(Libro[] b, Libro p){ //REQUIRES: b,p diversi da null //EFFECTS: restituisce true se p occorre in b, altrimenti false} public static String cerca(Libro[] b, String a){ //REQUIRES: b,p diversi da null //EFFECTS: restituisce il titolo di un Libro //appartenente ad l con autore a, se non ce ne // sono la stringa vuota} public static String all-copie(Libro[] b, String a, String t){ //REQUIRES: b,a,t diversi da null //EFFECTS: restituisce il numero di copie in b del //Libro che ha autore a e titolo t } }
Attenzione Le variabili d’istanza che implementano Libro sono private (non sono visibili nella classe ProcLibro) I metodi statici devono essere implementati usando le operazioni, fornite dalla specifica del tipo di dato Libro