• Non ci sono risultati.

Strutture dati: array & co.

N/A
N/A
Protected

Academic year: 2022

Condividi "Strutture dati: array & co."

Copied!
25
0
0

Testo completo

(1)

Strutture dati: array & co.

Fondamenti di programmazione Java

Matteo Baldoni

Dipartimento di Informatica

Universita` degli Studi di Torino C.so Svizzera, 185 I-10149 Torino [email protected]

(2)

2

Array

Gli array sono oggetti veri e propri (e quindi vanno prima creati esplicitamente dal programmatore per essere

utilizzati)

Hanno una dimensione fissa (dopo la creazione)

Esistono solo unidimensionali (ma e` possibile definire array di array)

Il primo elemento ha indice “0”

La creazione avviene mediante l’operatore new

(3)

Array

Es.: la dichiarazione di un array che puo` contenere 100 numeri interi

Gli elementi saranno indicizzati da 0 a 99

L'interprete controlla che gli indici siano sempre

nell'intervallo specificato al momento della creazione

int[] arrayOfInt = new int[100];

operatore che permette di

creare un oggetto

numero di elementi dell’array nome dell’array

tipo di un elemento dell’array

tipo array

arrayOfInt[5]

indice

(4)

4

Array

Il nome dell’array e` un puntatore ad una struttura contenente i vari elementi

ma differenza del C/C++ il nome dell’array non indica anche il primo elemento dell’array stesso (non esiste un’aritmetica dei puntatori)

In Java non esistono analoghi di & e * del C/C++

int array_interi[];

int *array_interi;

array_interi[2]

*(array_interi + 2)

in C/C++ sono equivalenti

in C/C++ sono equivalenti

(5)

Array

Se assegno un array ad un altro non copio gli elementi che esso contiene ma semplicemente il valore del

puntatore, i due array condivideranno la stessa struttura (esiste pero` arraycopy nella classe System)

length (campo read-only) restituisce la lunghezza di un array

int[] arrayOfInt = new int[6];

[…]

int[] altroArrayOfInt;

[…]

altroArrayOfInt = arrayOfInt;

[…] stampa 6

arrayOfInt

altroArrayOfInt

(6)

6

Array

Contatore cont[];

cont

(7)

Array

Contatore cont[];

cont = new Contatore[3];

cont

(8)

8

Array

Contatore cont[];

cont = new Contatore[3];

cont[0] = new Contatore(10);

cont contatore

10

(9)

Inizializzazione di array

Mediante un loop (tipicamente un ciclo for)

oppure durante la definizione stessa

array anonimi come parametri attuali

int[] arrayOfInt = new int[100];

for (int i=0; i<100; i++) arrayOfInt[i] = i;

int[] arrayOfInt = {1, 2, 4, 10}; utile per array con pochi elementi

new int[] {1, 2, 4, 10} utile per essere passato come parametro attuale di un metodo senza dover creare solo per questo una variabile

[…]

a.metodo(new int[] {1, 2, 4, 10});

(10)

10

Array multidimensionali

Ossia array di array (ma non matrici!)

Ossia un elemento di un array puo` essere a sua volta un array

int[][] arrayOfArrayOfInt = new int[10][5];

int[][] arrayOfArrayOfInt = new int[10][];

for (int i=0; i<10; i++)

arrayOfArrayOfInt[i] = new int[5];

int[][] arrayOfArrayOfInt = new int[10][];

for (int i=0; i<10; i++)

arrayOfArrayOfInt[i] = new int[i];

quadrato di

elementi 10 x 5

triangolo di elementi

(11)

Array

Gli array sono oggetti di “prima classe”

Gli array sono built-in nel linguaggio

L’operatore [] e`un costruttore di tipo!

public class Counter { private int c;

[…]

}

Counter[] arrayOfCounters = new Counter[10];

Definisce il tipo Counter

Definisce il tipo array di Counter

(12)

12

Array

class ProvaArray { public static void

main(String[] args) { ClasseUno[] arrayClasseUno;

ClasseDue[] arrayClasseDue;

ClasseTre[] arrayClasseTre;

ClasseDue[] arrayClasseDueBis;

arrayClasseDue = new ClasseDue[]

{new ClasseDue(2,3), new ClasseDue(3,4)};

arrayClasseUno = arrayClasseDue;

arrayClasseDueBis =

(ClasseDue[]) arrayClasseUno;

arrayClasseTre = new ClasseTre[]

{new ClasseTre("ab"), new ClasseTre("cd")};

arrayClasseUno = arrayClasseTre;

...

} Upcast di tutti gli elementi

Downcast di tutti gli elementi Errore!

(13)

Array

class ProvaArray { public static void

main(String[] args) { ClasseUno[] arrayClasseUno;

ClasseDue[] arrayClasseDue;

...

arrayClasseDue = new ClasseDue[]

{new ClasseDue(2,3), new ClasseDue(3,4)};

...

arrayClasseUno = arrayClasseDue;

...

arrayClasseUno[0] = new ClasseUno(2);

}

Errore a run-time!!

A tempo di compilazione è corretto

assegnare ad un campo dell’array di tipo ClasseUno un elemento di tipo ClasseUno ma a run-time questo contiene un elemento di tipo ClasseDue,

(14)

14

La classe java.util.Arrays

Mette a disposizione una serie di metodi statici di utilita` per trattare con array:

equals

fill

sort

binarySearch

I metodi sono overloaded per ogni tipo primitivo e per Object.

Fa uso di equals e non di ==

Fa uso di compareTo

dell’interfaccia Comparable per parametrizzare l’algoritmo di

ordinamento rispetto gli elementi Permette di usare anche oggetti

di tipo Comparator (interfaccia) per parametrizzare rispetto al confronto

(15)

Strutture dati: Interfacce

Collection: un arbitraio gruppo di oggetti

List: un gruppo di oggetti memorizzati in una data sequenza

Set: un gruppo di oggetti senza duplicati

Map: un gruppo di coppie

(oggetti) chiave-valore Sono tutte interfacce!

(16)

16

Strutture dati: Implementazioni

Ogni interfaccia ha piu` implementazioni che possono essere scelte in modo indifferente a seconda delle esigenze (anche di efficienza)

(17)

Strutture dati

Tassonomia completa delle strutture dati disponibili nel package java.util

Si noti Vector

ancora consentito sebbene gli venga ora preferito

ArrayList

(18)

18

Strutture dati

Gli oggetti che possono essere contenuti in una qualsiasi struttura dati sono di tipo Object, quindi un oggetto

qualsiasi

Un oggetto di tipo, ad esempio, ArrayList puo` contenere oggetti di tipo diverso, anche non omogenei (perche`

comunque di tipo Object)

Viene persa l’informazione sul tipo di un oggetto quando è inserito in una struttura dati di questo genere (è come fare upcasting ad Object!)

Estratti gli oggetti è necessario fare downcasting per poterli riutilizzare correttamente (invocare metodi della loro classe di appartenenza), in contrapposizione agli array

(19)

Un esempio

Tratto da: B. Eckel, Thinking in Java, Prentice Hall, 2000.

Cap. 9, pag. 450 e seguenti.

public class Cat {

private int catNumber;

Cat(int i) { catNumber = i; } void print() {

System.out.println("Cat #" + catNumber);

} }

public class Dog {

private int dogNumber;

Dog(int i) { dogNumber = i; } void print() {

System.out.println("Dog #" + dogNumber);

(20)

20

Un esempio

import java.util.*;

public class CatsAndDogs {

public static void main(String[] args) { ArrayList cats = new ArrayList();

for(int i = 0; i < 7; i++) cats.add(new Cat(i));

cats.add(new Dog(7));

for(int i = 0; i < cats.size(); i++) ((Cat)cats.get(i)).print();

} }

ArrayList non ha nessun

riferimento a cosa conterra`

in seguito!

Posso benissimo aggiungere un oggetto di tipo Dog in cats!

Durante la compilazione non viene rilevato nessun errore ma durante l’esecuzione (run-time) verra` sollevata un’eccezione (ClassCastException) poiche` verra` trovato un elemento non di tipo Cat (il downcast non è un cast alla C ma sono una

verifica che l’oggetto sia effettivamente di un certo tipo) Senza downcast non potrei invocarlo

(21)

Un esempio

public class Cat1 {

private int catNumber;

Cat(int i) { catNumber = i; } public String toString() { return "Cat #" + catNumber;

} }

public class Dog1 {

private int dogNumber;

Dog(int i) { dogNumber = i; } public String toString() { return "Dog #" + dogNumber;

} }

A differenza di prima abbiamo un metodo

toString() per stampare

(22)

22

Un esempio

import java.util.*;

public class CatsAndDogs {

public static void main(String[] args) { ArrayList cats = new ArrayList();

for(int i = 0; i < 7; i++) cats.add(new Cat1(i));

cats.add(new Dog1(7));

for(int i = 0; i < cats.size(); i++) //((Cat)cats.get(i)).print();

System.out.println(cats.get(i).toString());

} }

Non viene sollevata nessuna eccezione durante l’esecuzione!!

Tutto funziona perfettamente. Questo perche` abbiamo fatto overriding di un metodo appartenente alla classe Object e quindi sopraclasse sia di Cat1 che di Dog1. Il binding

dinamico associera` il corretto codice durante l’esecuzione

Posso aggiungere

un oggetto di tipo Dog Viene invocato

implicitamente non è necessario scriverlo

Durante la compilazione nessun errore poiche`

String toString() è un metodo disponibile in Object

(23)

Il metodo toString()

E` il metodo che viene automaticamente richiamato per la conversione di un oggetto in una stringa da stampare

Puo` essere ridefinito per adattarlo alle proprie esigenze

(24)

24

Il metodo toString()

public class Counter {

public Counter() {

nomeContatore = "Contatore anonimo";

}

public Counter(int val){

c = val;

nomeContatore = "Contatore anonimo";

}

public Counter(int val, String nome){

c = val;

nomeContatore = nome;

} […]

public void setName(String nome) { nomeContatore = nome;

}

public String toString(){

return ("Valore contatore " + nomeContatore + ": " + c);

}

private int c;

private String nomeContatore;

}

overriding dell’omonimo metodo nella classe Object

Un nome al contatore

(25)

Iteratori

È un oggetto che permette di attraversare agevolmente una struttura dati qualsiasi (indipendentemente dalla sua implementazione)

nest(), hasNext(), remove()

import java.util.*;

public class CatsAndDogs2 {

public static void main(String[] args) { Collection cats = new ArrayList();

for(int i = 0; i < 7; i++) cats.add(new Cat(i));

Iterator e = cats.iterator();

while(e.hasNext())

((Cat)e.next()).print();

Riferimenti

Documenti correlati

• Il tempo impiegato per trovare lo slot desiderato (quello che contiene la chiave desiderata, oppure quello libero in cui inserire l'oggetto) dipende (anche) dalla sequenza

• quando coloriamo un nodo u di G di nero (cioè ogni volta che finiamo di visitare un nodo di G), inseriamo u in testa alla lista. • dopo che abbiamo visitato tutti i nodi di G,

Autore: Rio Chierego (email: [email protected] - sito web: http://digilander.libero.it/rijo) Pag.. Quindi il vantaggio di fornire una soluzione astratta del problema permette

•  A partire dalla metà degli anni '80, sono stati realizzati numerosi sistemi di gestione di basi di dati a oggetti (ODBMS) — di tipo prototipale o commerciale.. •  I

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.29. Merge sort: codice

• prendendo un dato alla volta dalla sotto-sequenza il cui primo dato è

■ Gli oggetti che possono essere contenuti in una qualsiasi struttura dati sono di tipo Object, quindi un oggetto qualsiasi. ■ Un oggetto di tipo, ad esempio, ArrayList puo`

In definitiva l algoritmo di Dijkstra è più conveniente rispetto a quello di Bellman-Ford,mentre l ultimo algoritmo citato ha una duttilità maggiore perché é in grado di trovare il