Ripasso di Java - dei.unipd.itcapri/DA1/MATERIALE/RipassoJava1819.pdf · Tempi in secondi. A.A....

48
A.A. 18/19 DA1 – A. Pietracaprina 1 Ripasso di Java

Transcript of Ripasso di Java - dei.unipd.itcapri/DA1/MATERIALE/RipassoJava1819.pdf · Tempi in secondi. A.A....

A.A. 18/19 DA1 – A. Pietracaprina 1

Ripasso di Java

A.A. 18/19 DA1 – A. Pietracaprina 2

Programma Stand-alone

File: MyProgram.java

import … ; // import a package or a class

public class MyProgram {

public static void main(String[] args) {

…….. // corpo del metodo main

}

/* eventuali altri metodi */

}

A.A. 18/19 DA1 – A. Pietracaprina 3

Compilazione:

Esecuzione:

Programma stand-alone

Oss. In alternativa si può usare un Integrated Development

Environment (IDE), ad es. IntelliJ IDEA, Eclipse, JBuilder

java MyProgram

Crea un bytecode MyProgram.class eseguibile sulla Java Virtual Machine (JVM)

javac MyProgram.java

Oss. Richiede che la directory corrente sia nel CLASSPATH. Altrimenti usiamo:java –cp . MyProgram

A.A. 18/19 DA1 – A. Pietracaprina 4

Esempio

Calcolo dell’n-esimo numero di Fibonacci F(n)

Def. successione di Fibonacci:

F(0)=0, F(1)=1, F(n)=F(n-2)+F(n-1) se n≥2, n intero

GOAL: confrontiamo i tempi di esecuzione dell’algoritmo iterativo e di quello ricorsivo per il calcolo di F(n).

File: Fibonacci.java

A.A. 18/19 DA1 – A. Pietracaprina 5

Esempio: calcolo dell’n-esimo numero di Fibonacci

import java.util.Scanner;

public class Fibonacci{public static void main(String[] args) {

Scanner input = new Scanner(System.in);

System.out.print("Which Fibonacci number do you want?");int n = input.nextInt();

//compute F(n) with iterFibonacci and measure running timeSystem.out.println("\nLet's start the iterative algorithm!");long time1 = System.currentTimeMillis();

long f = iterFibonacci(n);long time2 = System.currentTimeMillis();

System.out.println("F(n)="+f);System.out.println("Time of iterFibonacci="+(time2-time1));

A.A. 18/19 DA1 – A. Pietracaprina 6

Esempio: calcolo dell’n-esimo numero di Fibonacci

…….//compute F(n) with recFibonacci and measure running timeSystem.out.println("\nLet's start the recursive algorithm!");time1 = System.currentTimeMillis();

f = recFibonacci(n);time2 = System.currentTimeMillis();

System.out.println("F(n)="+f);System.out.println("Time of recFibonacci="+(time2-time1));

}

A.A. 18/19 DA1 – A. Pietracaprina 7

System.in: variabile statica (classe System) di tipo InputStream associata alla “standard input device” (default: tastiera con echo su Java console)

System.out: variabile statica (classe System) di tipo PrintStream associata alla “standard output device” (default: Java console)

Scanner: classe che permette di leggere un oggetto di tipo InputStream (ad es., System.in) dividendolo in token separati da delimitatori (ad es., spazi, tab, newline). I token possono essere trasformati in tipi diversi utilizzando il metodo nextType() (ad es., nextInt()). I metodi nativi di System.in che derivano dalla classe InputStream sono di più basso livello (ad es., lettura di byte)

currentTimeMillis(): metodo statico della classe System che restituisce il tempo dal 1/1/1970 misurato in millisecondi

Esempio: calcolo dell’n-esimo numero di Fibonacci

A.A. 18/19 DA1 – A. Pietracaprina 8

/*Iterative algorithm*/public static long iterFibonacci(int n){

if(n<=1) return n;long x=0; long y=1; long tmp;for(int i=2; i<=n; i++){

tmp = x; x = y; y = tmp+x;//At the end of the ith iteration, x=F(i-1) and y=F(i)

}return y;

}/*Recursive algorithm*/public static long recFibonacci(int n){

if ((n== 0) || (n == 1)) return n; // base cases return recFibonacci(n-1) + recFibonacci(n-2);

}} // end of class Fibonacci

Esempio: calcolo dell’n-esimo numero di Fibonacci

A.A. 18/19 DA1 – A. Pietracaprina 9

Esercizi

Esercizi

1. Implementare l’algoritmo per il calcolo di F(n) basato sul calcolo ricorsivo delle potenze, e confrontarne il tempo di esecuzione con quelli degli algoritmi iterativo e ricorsivo.

2. Implementare findBrute e findKMP confrontandone i tempi di esecuzione.

n=30

F(n)=832040

n=40

F(n)≈108

n=50

F(n)≈1010

iterFibonacci 0 0 0

recFibonacci 0.01 1.2 143.8

Tempi in secondi

A.A. 18/19 DA1 – A. Pietracaprina 10

Caratteristiche Java e approccio Object Oriented

Portabilità:

• Java Virtual Machine (JVM): macchina virtuale che fornisce un modo platform-independent di eseguire il codice. E’ implementata su tutte le principali piattaforme (Hw+S.O.)

MyClass.java → MyClass.class (bytecode)

• Range dei tipi base definiti dal linguaggio

• int → 32 bit, long → 64 bit

• float → 32 bit, double → 64 bit

• char → 16 bit (Unicode)

• Tutti i tipi base (tranne boolean e void) sono con segno.

A.A. 18/19 DA1 – A. Pietracaprina 11

Modularità:

• Applicazione ≡ insieme di oggetti interagenti

• Un oggetto è un’istanza di una classe che definisce

Variabili di istanza (instance variables o fields)

Metodi (methods)

La classe rappresenta il “tipo” dell’oggetto

Integer i = new Integer(5);

Definizione della variabile i di tipo Integer

Creazione di un oggetto di tipo Integer

Caratteristiche Java e approccio O.O.

A.A. 18/19 DA1 – A. Pietracaprina 12

Robustezza:

• Funzionalità suddivise in componenti logiche

Adattabilità:

• Modifiche apportabili a singole componenti senza dover intaccare tutto il codice

Riusabilità:

• Singole componenti possono essere riutilizzate da altre applicazioni

Caratteristiche Java e approccio O.O.

A.A. 18/19 DA1 – A. Pietracaprina 13

Astrazione e Incapsulamento (Information Hiding):

• Si astrae la specifica delle funzionalità, separandola dalla loro implementazione

• Uso delle funzionalità solo in base alla specifica

• L’implementazione delle funzionalità è nascosta

• Gli errori sono più confinati (-> robustezza)

• Possibilità di cambiare l’implementazione senza cambiare la specifica (-> adattabilità)

• Nel caso delle strutture dati, questo approccio dà origine alla nozione di Abstract Data Type (ADT)

Caratteristiche Java e approccio O.O.

A.A. 18/19 DA1 – A. Pietracaprina 14

Abstract Data Type

• Modello di struttura dati che specifica: il tipo di dati; le operazioni disponibili per accedere a essi e modificarli; e i parametri usati da tali operazioni.

• In Java si realizza principalmente tramite interfacce che contengono solo dichiarazioni di costanti e dichiarazioni di

metodi senza corpo.

• In Java esistono poi anche classi astratte che sono classi che possono contenere anche dichiarazioni di metodi senza corpo (come le interfacce)

Caratteristiche Java e approccio O.O.

A.A. 18/19 DA1 – A. Pietracaprina 15

INTERFACCIA

Caratteristiche Java e approccio O.O.

public interface A {public int a1();public boolean a2();

}public class X implements A {

public int a1() {…}public boolean a2() {…}public void b() {…}

}…A var1 = new A(); NO!

A var1 = new X(); OK!

A

X

implements

Ad es., java.lang.Stringimplementsjava.lang.Comparable

A.A. 18/19 DA1 – A. Pietracaprina 16

Ereditarietà (Inheritance)

• Si importano in una classe le caratteristiche di un’altra classe aggiungendone di nuove e/o specializzandone alcune

• In Java: extends (subclass → superclass)

Caratteristiche Java e approccio O.O.

public class S {public void a() {…}public void b() {…} public int c() {…}

}public class T extends S {

/* inherits b() and c() */float y; // addedpublic void a() {…} // specializedpublic boolean d() {…} // added

}

S

T

extends

Superclass

Subclass

Ogni classe estende implicitamente

java.lang.Object

A.A. 18/19 DA1 – A. Pietracaprina 17

Esempi

Caratteristiche Java e approccio O.O.

S var = new S();…var.a(); // metodo di Svar.b(); // metodo di Svar.d(); // ERRORE! (var è dichiarata di tipo S)((T) var).d(); // ERRORE (var è definita di tipo S)

/* var dichiarata di tipo S e definita di tipo T */S var = new T(); …var.a(); // metodo di T (polimorfismo)var.b(); // metodo di Svar.d(); // ERRORE! (var è di tipo S)((T) var).d(); // metodo di Tcast

S

T

extends

A.A. 18/19 DA1 – A. Pietracaprina 18

Overloading e Polimorfismo

• Signature di un metodo: nome del metodo + numero e tipo dei parametri (in ordine da sx verso dx). Il nome dei parametri e il tipo di ritorno non importano.

• Overloading: possibilità di avere due metodi nella stessa classe o nella stessa gerarchia di classi che hanno lo stesso nome ma signature diverse. Ad es.

a(); a(int x, float y);

• Polimorfismo (overriding): possibilità di avere due metodi con la stessa signature all’interno della stessa gerarchia (in classi diverse). I metodi devono avere lo stesso return type. Ad es. metodo void a() in S e T nell’esempio.

Caratteristiche Java e approccio O.O.

A.A. 18/19 DA1 – A. Pietracaprina 19

Ereditarietà multipla per interfacce (non per classi!)

Caratteristiche Java e approccio O.O.

public interface A {…}public interface B {…}public interface C extends A, B

{…} C

A

extends

B

extends

public class D implements A, B {// deve implementare tutti i metodi di A e B}public class D implements C {// deve implementare tutti i metodi di A e B// e quelli (eventuali) aggiuntivi di C}

A.A. 18/19 DA1 – A. Pietracaprina 20

Programmazione Generica (generics)

• È un tipo di polimorfismo, introdotto da Java SE 5. Permette l’uso di variabili di tipo nella definizione di classi, interfacce

e metodi. Si parla in questo caso di classi/interfacce

generiche e metodi generici.

• Nel creare un’istanza di una classe generica si specifica il tipo (actual type) da sostituire con la variabile di tipo. L’actual type non può essere un tipo primitivo (ad es., int) ma deve essere una classe che estende Object

• Nell’invocazione di un metodo generico la sostituzione della variabile di tipo con un actual type è fatta automaticamente in base ai parametri passati.

• L’uso delle classi/interfacce generiche evita il ricorso a parametri di tipo “Object” e l’uso frequente di cast.

A.A. 18/19 DA1 – A. Pietracaprina 21

Esempio: classe generica

Programmazione generica

/* la seguente classe permette di usare al posto di E solo estensioni della classe/interfaccia S */

public class MyClass1<E extends S> {…}

public class MyClass<E> {E var1; // E indica un tipo qualsiasi (tranne i tipi base)E a() {…}void b(E param1) {

var1 = param1; //OK!E s = new E(); //NO! il compilatore segnala un errore

}}….MyClass<Integer> x = new MyClass<Integer>(); // istanza

A.A. 18/19 DA1 – A. Pietracaprina 22

Esempio: metodo generico

Programmazione generica

/* definizione */public static <E> void myMethod (E param){…}

N.B. la specifica del tipo generico deve comparire dopo i modificatori (ad es. publice static) e prima del tipo di ritorno

/* invocazione */myMethod (x); // E sostituito automaticamente con il tipo di x

ADT ELEMENTARI

• LISTA (LIST)

• Position-based

• Index-based

• PILA (STACK)

• CODA (QUEUE)

A.A. 18/19 DA1 – A. Pietracaprina 24

LISTA (LIST): collezione di elementi organizzati secondo un ordine lineare tale per cui è identificabile il primo elemento, il secondo, … , e l’ultimo. Un elemento può essere acceduto tramite

• position = contenitore dell’elemento (nodo)

• index = intero ≥ 0 che indica il numero di elementi che precedono quello considerato

X Y Z

positionelemento

index = 1

Lista

A.A. 18/19 DA1 – A. Pietracaprina 25

Lista position-based ([GTG14, Sect. 7.3])

Lista position-based

INTERFACCE

CLASSI

implements

Position<E>

Node<E>

PositionalList<E>

LinkedPositionalList<E>

implements

usa

Position: ADT che rappresenta il concetto di “nodo”

PositionalList: ADT che rappresenta il concetto di lista con accesso tramite posizione

Node: implementa Position come nodo di una lista doubly linked

LinkedPositionalList: implementa PositionList tramite Node

E: variabile di tipo che rappresenta il tipo degli elementi

usa

A.A. 18/19 DA1 – A. Pietracaprina 26

Interfaccia Position<E> (file Position.java)

public interface Position<E> {/** Return the element stored at this position */public E getElement();

}

Lista position-based

A.A. 18/19 DA1 – A. Pietracaprina 27

Interfaccia PositionalList<E> (file PositionalList.java)

public interface PositionalList<E> {/** Returns the number of elements in this list. */public int size();/** Returns whether the list is empty. */public boolean isEmpty();/** Returns the first node in the list. */public Position<E> first();/** Returns the last node in the list. */public Position<E> last();/** Returns the node after a given node in the list. */public Position<E> after(Position<E> p);/** Returns the node before a given node in the list. */public Position<E> before(Position<E> p);….

Lista position-based

A.A. 18/19 DA1 – A. Pietracaprina 28

Interfaccia PositionalList<E> (continua)

…./** Inserts an element at the front of the list. */public void addFirst(E e);/** Inserts and element at the back of the list. */public void addLast(E e);/** Inserts an element after the given node in the list. */public void addAfter(Position<E> p, E e);/** Inserts an element before the given node in the list. */public void addBefore(Position<E> p, E e);/** Removes a node from the list, returning the element stored there. */public E remove(Position<E> p);/** Replaces the element stored at the given node, returning old element. */public E set(Position<E> p, E e);

}

Lista position-based

A.A. 18/19 DA1 – A. Pietracaprina 29

Classe Node<E> (file Node.java): implementazione di Position<E>

nextprevYX Z

Node<E>

Elemento di tipo E

Lista position-based

N.B. In [GTG14] è una nested static class dentro LinkedPositionalList<E>

A.A. 18/19 DA1 – A. Pietracaprina 30

public class Node<E> implements Position<E> {private Node<E> prev, next; // References to the nodes before and afterprivate E element; // Element stored in this position/** Constructor */public Node(E e, Node<E> p, Node<E> n) {

element = e;prev = p;next = n;

}public E getElement() { return element; } // Method from interface Position// Accessor methodspublic Node<E> getPrev() { return prev; }public Node<E> getNext() { return next; }// Update methodspublic void setElement(E e) { element = e; }public void setNext(Node<E> n) { next = n; }public void setPrev(Node<E> p) { prev = p; }

} // end of class Note

Lista position-based

A.A. 18/19 DA1 – A. Pietracaprina 31

Classe LinkedPositionalList<E> (file LinkedPositionalList.java):implementazione di PositionalList<E>

header trailer

Nodi con elementi

Sentinelle

Lista position-based

A.A. 18/19 DA1 – A. Pietracaprina 32

Classe LinkedPositionalList<E> (continua)

public class LinkedPositionalList<E> implements PositionalList<E> {private int size=0; // Number of elements in the listprivate Node<E> header, trailer; // Special sentinels/** Constructor that creates an empty list; O(1) time */public LinkedPositionalList() {

header = new Node<E>(null, null, null); // create headertrailer = new Node<E>(null, header, null); // create trailerheader.setNext(trailer); // make header and trailer point to each other

}/** Returns the number of elements in the list; O(1) time */public int size() { return size; }/** Returns whether the list is empty; O(1) time */public boolean isEmpty() { return (size == 0); }….

Lista position-based

A.A. 18/19 DA1 – A. Pietracaprina 33

Classe LinkedPositionalList<E> (continua)

…/** Checks if position is valid for this list and converts it to Node */private Node<E> validate(Position<E> p) {…}/** Returns the given node as a Position (or null if it is a sentinel)*/private Position<E> position(Node<E> node) {…}

public Position<E> first() { return position(header.getNext()); }public Position<E> after(Position<E> p) {

Node<E> node = validate(p);return position(node.getNext());

}...

Lista position-based

A.A. 18/19 DA1 – A. Pietracaprina 34

Classe LinkedPositionalList<E> (continua)

…/** Adds element e to the linked list between the given nodes*/private Position<E> addBetween(E e, Node<E> pred, Node<E> succ) {

Node<E> newest = new Node<E>(e, pred, succ);pred.setNext(newest);succ.setPrev(newest);size++;return newest;

}

public void addAfter(Position<E> p, E e) { Node<E> node = validate(p);return addBetween(e,node,node.getNext());

}...

Lista position-based

A.A. 18/19 DA1 – A. Pietracaprina 35

public interface List<E> {/** Returns the number of elements in this list. */public int size();/** Returns whether the list is empty. */public boolean isEmpty();/** Inserts an element e to be at index i, shifting all elements after this. */public void add(int i, E e);/** Returns the element at index i, without removing it. */ public E get(int i) /** Replaces the element at index i with e, returning the previous element at i. */ public E set(int i, E e) /** Removes and returns the element at index i shifting left subsequent elements. */ public E remove(int i)

}

Lista index-based ([GTG14, Sect. 7.1])

Lista index-based

Oss. Presente nel package java.util di Java

A.A. 18/19 DA1 – A. Pietracaprina 36

PILA (STACK): collezione di elementi inseriti e rimossi in base al principio Last-In First-Out (LIFO)

public interface Stack<E> {/** Returns the number of elements in this list. */public int size();/** Returns whether the list is empty. */public boolean isEmpty();/** Inserts an element e at the top of the stack. */public void push(E e);/** Returns the element at the top of the stack without removing it. */ public E top();/** Removes and returns the element at the top of the stack. */ public E pop();}

Oss. Nel package java.util di Java esiste una classe Stack, ma si consiglia di usare Deque (vedi prossimo lucido)

Pila

A.A. 18/19 DA1 – A. Pietracaprina 37

CODA (QUEUE): collezione di elementi inseriti e rimossi in base al principio First-In First-Out (FIFO)

public interface Queue<E> {/** Returns the number of elements in this list. */public int size();/** Returns whether the list is empty. */public boolean isEmpty();/** Inserts an element e at the rear of the queue. */public E enqueue(E e);/** Returns but does not remove the first element of the queue (null if empty). */ public E first();/** Removes and returns the first element of the queue (null if empty). */ public E dequeue(); }

Oss. Nel package java.util esiste una classe Deque (Double-ended queue) che permette inserimento e rimozione sia in testa che in coda, ovvero Pila+Coda. Java ne suggerisce l’uso al posto della semplice Pila

Coda

A.A. 18/19 DA1 – A. Pietracaprina 38

ESEMPIO

InsertionSort

A.A. 18/19 DA1 – A. Pietracaprina 39

Cosa possiamo ordinare?

Solo oggetti che implementano l’interfaccia java.lang.Comparable<E>, perché contengono il metodo per confrontare: public int compareTo(E o)

InsertionSort

public interface Comparable<E> {public int compareTo(E o);

}

Ad es. la classe Integer implementa Comparable<Integer>

x.compareTo(y):<0 se x<y=0 se x=y>0 se x>y

A.A. 18/19 DA1 – A. Pietracaprina 40

Implementazione su lista index-based: schema delle classi

Sort

usa

Programma stand-alone

implements

List<E>

ArrayList<E>

InsertionSort

• L’interfaccia List<E> e la classe ArrayList<E> sono presenti nel package java.util dell’API (Application Programming Interface) di java

• ArrayList implementa una lista index-based tramite array estendibile (extendable array)

File: Sort.java

Compilazione: javac Sort.java

A.A. 18/19 DA1 – A. Pietracaprina 41

import java.util.*;public class Sort {public static void main(String[] args) {

Scanner input = new Scanner(System.in);List<Integer> L = new ArrayList<Integer>();System.out.print("Input number of ints to be sorted: ");int n = input.nextInt();for (int i=0; i<n; i++) {System.out.print("Input next int: ");L.add(i, new Integer(input.nextInt()));

}sort(L); // call to sort methodfor (int i=0; i<n; i++) System.out.println(L.get(i));

}

InsertionSort

Implementazione su lista index-based (continua)

A.A. 18/19 DA1 – A. Pietracaprina 42

public static <E extends Comparable<E>> void sort(List<E> L) {if (L.size() <= 1) return; // L is already sorted in this caseint i, j, n=L.size();for (i=1; i<n; i++) {E curr = L.get(i);j = i-1;while ((j >= 0) && (curr.compareTo(L.get(j)) < 0)) {L.set(j+1, L.get(j)); // move index-j element to index j+1 j=j-1;

} // end whileL.set(j+1,curr);

} // end for} // end void sort

} // end class Sort

InsertionSort

Implementazione su lista index-based (continua)

A.A. 18/19 DA1 – A. Pietracaprina 43

Sort

usa

Programma stand-alone

implements

Position<E>

Node<E>

PositionalList<E>

LinkedPositionalList<E>

implements

usa

usa

File: Position.java, PositionalList.java, LinkedPositionalList.java Node.java, Sort.java

Compilazione: javac Sort.java

Implementazione su lista position-based: schema delle classi

InsertionSort

A.A. 18/19 DA1 – A. Pietracaprina 44

Iterator e Iterable

Iteratore: oggetto che permette di esaminare gli elementi di una collezione (ad es. una lista), uno alla volta.

/* In package java.util */public interface Iterator<E> {

/** Returns true if there is a “next element”. */public boolean hasNext();/** Returns the “next element” of the collection. */public E next();

}

Iterator e Iterable ([GTG14, Sect. 7.4])

Oss: l’ordine con il quale gli elementi della collezione sono restituiti non è specificato a priori e dipende dall’implementazione dell’iteratore.

A.A. 18/19 DA1 – A. Pietracaprina 45

Iterator e Iterable

Iterable: collezione che prevede un metodo iterator() che restituisce un iteratore ai propri elementi.

/* In package java.util */public interface Iterable<E> {

/** Returns an iterator to the elements of the collection. */Iterator<E> iterator();

}

A.A. 18/19 DA1 – A. Pietracaprina 46

Collection framework

Fa parte del package java.util e contiene:

Interfacce di varie collezioni Classi che implementano le interfacce Algoritmi (polimorfi) per operare su collezioni (ad es. sorting) Ampio uso della programmazione generica

Collection Framework ([GTG14, Sect. 7.5])

A.A. 18/19 DA1 – A. Pietracaprina 47

Riepilogo

• Compilazione ed esecuzione di programmi in Java

• Caratteristiche O.O., con riferimento a Java

• Abstract Data Type (ADT), con riferimento a Java

• ADT Elementari:

• Lista (position e index-based)

• Pila

• Coda

• Concetto di Iteratore e di Iterable

• Collection Framework

Sul sito del corso viene fornito il codice con l’implementazione completa di iterFibonacci, recFibonacci e di InsertionSort con Lista position-based e index-based

A.A. 18/19 DA1 – A. Pietracaprina 48

Esempi di domande da prima parte

1. Definire brevemente il concetto di Abstract Data Type(ADT) caratteristico dell’approccio object-Oriented, e spiegare in che modo Java permette di specificare un ADT

2. Descrivere le due interfacce Iterator e Iterable di Java e il loro utilizzo.