15. Le date in Java

Andrea Pastore 19/03/2020 0

Le date in Java sono memorizzate in oggetti appositi, che contengono il numero di secondi dal 01/01/1970. Ovviamente le date possono essere formattate in vari formati, ad esempio quello italiano che è gg/mm/aaaa, oppure quello inglese che è aaaa/mm/gg. Java mette a disposizione la classe Date per rappresentare le date e la classe Calendar per recuperare una data. Vediamo un esempio:

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone( "Europe/Rome"),Locale.ITALY);

La creazione di un oggetto di tipo Calendar è un po’ particolare: viene invocato il metodo getInstance come mostrato sopra, che prende in input la zona  temporale che ci interessa e il formato della data. Fatto questo è possibile recuperare le informazioni sulla data, con la riga di codice sottostante:

Date dataOggi = calendar.getTime();

 

Stampare una data

Per stampare una data dobbiamo creare un oggetto di tipo DateFormat e poi invocare il suo metodo format, passandogli come parametro la data.

DateFormat dateFormat = DateFormat.getDateInstance (DateFormat.SHORT, Locale.ITALY);

System.out.println("data oggi: "+dateFormat.format(dataOggi));

Il metodo getDateInstance della classe DateFormat prende in input come primo parametro il tipo di visualizzazione, nel nostro caso DateFormat.SHORT, che indica la stampa classica della data, ovvero nel formato gg/mm/aaaa. Ovviamente il formato è dato anche dal secondo parametro: se avessimo scritto:

DateFormat dateFormat = DateFormat.getDateInstance (DateFormat.SHORT, Locale.ENGLISH );

System.out.println("data oggi: "+dateFormat.format(dataOggi));

Avremmo ottenuto una stampa nel formato inglese ovvero mm/gg/aa.

 

Creare una data da una stringa

Possiamo creare un oggetto di tipo date a partire da una stringa, grazie alla classe SimpleDateFormat, ad esempio:

String s = "01/01/2019";

Date initDate = new SimpleDateFormat("dd/MM/yyyy").parse (s);

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

System.out.println(formatter.format(initDate));

Il costruttore di SimpleDateFormat prende in input il formato della data in input, nel nostro caso abbiamo scritto dd/mm/yyyy. Questo codice, però, può provocare un’eccezione se la data inserita in input non è corretta. Per questo motivo dobbiamo gestirlo usando il costrutto try catch:

	try {

String s = "01/01/2019";

Date initDate = new SimpleDateFormat("dd/MM/yyyy").parse (s);

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

System.out.println(formatter.format(initDate));

} catch (ParseException e) {

e.printStackTrace();

}
Potrebbero interessarti anche...

Andrea Pastore 19/03/2020

3. Le variabili in Java

Una variabile è un contenitore di dati che risiede nella memoria ram del computer. Di ogni variabile possiamo stabilire il nome e cosa deve contenere. Quando dobbiamo utilizzare quel valore lo richiamiamo.

 

Tipi di dati

Java è un linguaggio tipizzato, significa che per ogni variabile dobbiamo sempre specificare il tipo di dato. In Java ci sono una serie di tipi di dati elementari che sono riportati nella tabella sottostante:

Tipo di dato Spiegazione
int serve per memorizzare numeri interi
double serve per memorizzare numeri decimali. Attenzione, per separare i numeri decimali in Java si usa il punto e non la virgola
String serve per memorizzare il testo, dobbiamo inserire le virgolette
boolean tipo di dato che può avere due valori: true o false. Viene usato molto quando dobbiamo prendere decisioni

Scriviamo un programma che crea delle variabili:

public class HelloDanilo {

public static void main(String[] args) {

System.out.println("Stampo una stringa");



int a = 10;

int b = 20;

int addizione = a + b;

System.out.println(addizione);

}

}

Innanzitutto vediamo che anche questo programma come prima operazione stampa una stringa ( System.out.println("Stampo una stringa"); ). Successivamente vediamo che crea delle variabili intere:

		int a = 10;

int b = 20;

int addizione = a + b;

notiamo una cosa: alle prime due variabili sto assegnando un numero, alla terza invece sto chiedendo a Java di fare un’addizione delle due variabili che ho creato in precedenza. Altra cosa da notare con le variabili è che utilizzo l’operatore = per dare un valore alla variabile, questa operazione si chiama assegnamento.

L’ultimo comando di questo programma stampa la variabile addizione:

System.out.println(addizione);

notiamo una cosa: la parola addizione non contiene le virgolette. Questo perché stiamo chiedendo a Java di stampare una variabile. Quando Java interpreta questo codice sostituirà la parola addizione con il valore corrispondente, ed eseguirà la stampa. Se invece avessimo usato le virgolette, ovvero avremmo scritto:

System.out.println(“addizione”);

Java avrebbe considerato la parola come un testo da stampare e quindi avrebbe stampato “addizione”.

 

Convertire variabili da un tipo di dato ad un altro

Può capitare di dover convertire variabili in un altro formato, ad esempio da stringa a numero intero oppure da stringa a un numero decimale. Per fare questo ci sono dei comandi appositi. Supponiamo di avere queste variabili:

		String s1 = "10";

String s2 = "5.4";

Per convertire la stringa s1 in un numero intero bisogna usare questo comando:

		int numero1 = Integer.parseInt(s1);		

Per convertire la stringa s2 in un numero decimale bisogna usare questo comando:

		double numero2 = Double.parseDouble(s2);

Nota: se il tipo di dato non è corretto  (ad esempio provo a fare parseInt su s2, che essendo un numero decimale ha un punto) questi comandi genereranno un’eccezione.

 

Assegnare i nomi alle variabili

I nomi delle variabili, se scelti con criterio, possono aiutare a capire il motivo per cui sono state create. Osserviamo questo codice

int var1 = 10;

Nel momento in cui lo creiamo, ovviamente ci ricordiamo cosa va. Ma quando ci capiterà di dover apportare modifiche a quel codice a distanza di molto tempo non è detto che ci ricordiamo per quale motivo avevamo creato quella variabile. Certo lo potremmo capire andando a vedere il codice successivo, ma perderemmo del tempo. Per evitare ciò basta chiamare le variabili con nomi autoesplicativi, ad esempio:

	int anniUtente = 10;

in questo caso sarà facile capire cosa fa quella variabile, perché il suo nome ci spiega cosa fa.

 

Operatori aritmetici

Sulle variabili numeriche possono essere eseguite le operazioni aritmetiche, ad esempio:

	int b = a + 10;

Oltre alle 4 operazioni a cui siamo abituati Java ci mette a disposizione anche l’operatore modulo, per calcolare il modulo di un numero intero. Ecco la tabella degli operatori aritmetici:

Operatore Spiegazione
+ Operatore che consente di sommare due variabili: es a + b;
- Operatore che consente di sottrarre due variabili: es a - b;
* Operatore che consente di sottrarre due variabili: es a - b;
/ Operatore che consente di sottrarre due variabili: es a / b;
% Operatore che consente di eseguire l’operazione modulo, es a % b

 

Operatori di assegnamento

Quando noi creiamo una nuova variabile possiamo assegnare un valore iniziale, ad esempio scrivendo:

	int a = 10;

L’assegnamento si fa con l’operatore “=”. Negli esempi sopra abbiamo sempre assegnato un valore ad una variabile appena creata, ma potremmo anche non farlo e scrivere semplicemente:

	int a;

In questo secondo caso la variabile viene inizializzata o con un valore di default (come ad esempio nel caso dei numeri interi che vengono inizializzati a 0) o a null (tipi di dati più complessi che vedremo in seguito).

 

Altri operatori di assegnamento

Java mette a disposizione altri operatori di assegnamento, che non utilizziamo al momento della creazione di una variabile ma in seguito. Si tratta di scorciatoie che Java ci mette a disposizione. Il comando e l’azione svolta sono indicati nella tabella sottostante.

Operatore Azione svolta
+= è una scorciatoia per incrementare una variabile di una certa quantità equivale a scrivere: totale = totale + 10;
-= è una scorciatoia per sottrarre a una variabile una certa quantità equivale a scrivere: totale = totale - 10;
*= è una scorciatoia per moltiplicare una variabile per un numero equivale a scrivere: totale = totale * 10;

 

Assegnare  variabili casuali

Java, come tanti altri linguaggi di programmazione, è in grado di generare variabili casuali, grazie ad una classe chiamata Random. Le variabili generate in questo modo non sono in realtà totalmente casuali perché sono generate da un algoritmo, ma garantisce comunque  una certa varietà di risultati.

La prima cosa da fare è  importare una classe di utility che mette a disposizione Java, la classe Random:

import java.util.Random;

Nel nostro codice poi dobbiamo creare un oggetto (più avanti capiremo meglio cos’è) di tipo Random con questa riga di codice:

		Random generatore = new Random();

una volta creato questo oggetto possiamo creare diversi tipi di variabili random: numeri interi con questo codice:

		int rand = generatore.nextInt(2);

numeri decimali con quest’altro codice:

		double rand = generatore.nextDouble();

possiamo genereare anche una variabile di tipo booleano, con questo codice:

		boolean rand = generatore.nextBoolean();

 

Ecco il codice completo per creare una variabile casuale:

import java.util.Random;

public class HelloRandom {

public static void main() {

Random generatore = new Random();

int rand = generatore.nextInt(2);

// fa qualcosa col numero appena creato

}

}

 

Leggi tutto

Andrea Pastore 19/03/2020

18. Programmazione concorrente

Prima di introdurre questo agomento dobbiamo capire come funzionano i moderni processori: vediamo la foto di un’architettura di un processore intel:

Vediamo che è composto da varie parti: i core (le unità che di elaborazione, il codice che scriviamo viene elaborato da loro) una piccola memoria interna (da non confondersi con la memoria RAM, che non risiede nel processore) e poi una scheda video. Il numero di processi che può essere eseguito contemporaneamente dipende dal numero di core, quindi il processore mostrato in figura può eseguire quattro processi contemporaneamente. Il sistema operativo ha il compito di assegnare le risorse ad un processo: tra le altre cose deve decidere a quale processore assegnare il processo, controllare che non si blocchi, aggiornare la coda dei processi in attesa di essere eseguiti e molto altro ancora. Un processo resta in esecuzione per una frazione di secondo, poi se ha esaurito il compito viene terminato, altrimenti viene reinserito nella coda dei processi che in attesa di essere eseguiti.

I programmi moderni, a meno che non siano programmi molto piccoli sono composti da tanti processi in esecuzione sul proprio computer, ognuno con un compito. Un esempio è rappresentato dai browser web, come Firefox: l’architettura di questo browser prevede attualmente che ci sia un processo deputato a mostrare l’interfaccia (che mostra ad esempio le tab aperte) e altri processi che gestiscono le tab.

 

Lo scheduler del sistema operativo

Per stabilire quale processo debba essere eseguito ogni sistema operativo dispone di un software chiamato scheduler, che gestisce la coda dei processi tenendo conto di una serie di fattori: priorità, stato del processo e molti altri. Se il sistema operativo è progettato per gestire hardware in grado di gestire più thread contemporaneamente (ovvero tutti gli strumenti che utilizziamo maggiormente oggi: computer, telefonini, ma anche centraline di oggetti di uso comune come l’automobile) il suo ruolo si complica perché deve tenere conto anche degli altri thread. Ad esempio un thread di un processo potrebbe dover aspettare che un altro thread termini l’esecuzione.

 

La programmazione concorrente in Java

Java mette a disposizione due modi per creare processi concorrenti: la prima possibilità consiste nella creazione di una classe che estende la classe Thread, la seconda consiste nella creazione di una classe che implementa l’interfaccia Runnable. Le differenze dal punto di vista del codice sono minime, creiamo due classe Trhead_A e Trhead_B per vederle:

 

Classe che estende la classe Thread

public class Thread_A extends Thread {

private int contatore;



public Thread_A() {

this.contatore = 0;

}



public void run() {

this.contatore ++;

System.out.println("Trhead A: contatore= "+contatore);

}

}

 

Classe che implementa l’interfaccia Runnable

public class Thread_B implements Runnable{

private int contatore;

public Thread_B() {

this.contatore = 0;

}

@Override

public void run() {

this.contatore++;

System.out.println("Thread B: contatore="+contatore);

}

}

Notiamo che entrambe le classi hanno un metodo public void run(). Questo è un metodo necessario in quanto descrive le operazioni che deve fare il Thread. Nei nostri esempi qui sopra i thread incrementano un contatore e lo stampano.

 

Lanciare un Thread

A seconda del metodo che abbiamo scelto, i Thread si lanciano in due modi diversi. Se abbiamo scelto di creare le classi che estendono la classe Thread, come nel nostro esempio del Trhead_A, scriveremo:

Thread_A t  = new Thread_A();

t.start();

Se usiamo una classe che estende l’interfaccia Runnable creeremo prima un’istanza di quella classe, e un Trhead a partire da quella:

	Thread_B rc = new Thread_B();

Thread t1 = new Thread(rc);

t1.start();

Nota: in entrambi i casi per far partire un thread bisogna invocare il metodo start().

 

Assegnare la priorità ad un thread

È possibile impostare la priorità di un thread con il metodo setPriority. Java prevede per la priorità un valore da 1 a 10, se non lo impostiamo manualmente la priorità assegnata di default è 5. La classe Trhead dispone di tre costanti che sono:

MAX_PRIORITY = 10

MIN_PRIORITY = 1

MEDIUM_PRIORITY  = 5

Se ad esempio voglio impostare la priorità massima scriverò:

	t.setPriority(Thread.MAX_PRIORITY);

Per impostare altri valori sulla scala da 1 a 10 possiamo usare i numeri.

 

Mettere in pausa un thread

Può capitare di dover fermare un thread per un certo intervallo di tempo (ad esempio perché deve ripetere una determinata operazione dopo un tempo prestabilito), per questo Java mette a disposizione diversi metodi. Sleep, join e yeld.

 

sleep

prende in input il numero di millisecondi durante i quali il thread deve stare in pausa. Per invocarlo correttamente bisogna utilizzare il costrutto try .. catch, perché dobbiamo prevenire il fatto che un altro thread provi a chiamare il thread dove abbiamo invocato il metodo sleep:

	try {       	  		   

t1.sleep(10);

     } catch (InterruptedException ex) {

       // handle the error

       System.out.println("si è verificata un'eccezione");

     }

 

join

questo metodo serve a mettere in attesa il thread su cui è invocato fino a quando altri trhead al suo interno non abbiano terminato l’esecuzione. Supponiamo di avere un thread t1 che crea un thread t2 per eseguire un’operazione. L’istruzione:

	t2.sleep(10);

metterà in attesa il thread t1 fino a quando t2 non avrà terminato la sua esecuzione.

 

yeld

È un metodo statico che suggerisce allo scheduler di mettere in pausa il tread corrente per lasciare spazio ad altri. Viene invocato in questo modo:

	Thread.yield();
Leggi tutto

Andrea Pastore 19/03/2020

1. Le origini di Java e le sue caratteristiche

Java è un linguaggio di programmazione ad oggetti tra i più comuni al mondo, utilizzato praticamente in tutti i tipi di dispositivi, dai computer ai telefoni, distributori automatici e molto altro. Fu creato da Sun Microsystem nel 1995 ed è poi passato ad Oracle quando quest’ultima ha acquisito Sun.

 

La macchina virtuale Java

Una caratteristica di Java è quella di girare su tutti i sistemi operativi, senza che il codice venga ricompilato come avviene in altri linguaggi. Questa possibilità ci è data dalla Java Virtual Machine, che si occupa di leggere il codice Java tradurlo nel linguaggio macchina del dispositivo dove si trova.

 

Organizzazione del codice

Il codice Java è organizzato in classi, che sono contenute in package.  Per ora ci basti sapere che una classe è un file contenente codice Java, può richiamare altre classi per fare compiti specifici. Le classi a loro volta sono suddivise in metodi, che possono essere richiamati dalla stessa classe o da altre classi.

Un programma java può avere un numero variabile di classi che può essere anche molto elevato (si pensi per esempio a programmi come Eclipse). Un programma Java deve avere sempre una classe che viene chiamata quando il programma va in esecuzione. Questa classe è chiamata classe main, capiremo più avanti questo concetto.

Un package è una cartella che contiene le classi Java.  I progetti java possono essere molto vasti, quindi è necessario ordinare le classi in modo da essere consultabili. Ad esempio supponiamo di avere un programma di una biblioteca, un package potrebbe contenere tutte le classi Java deputate al salvataggio dei dati e un altro potrebbe contenere tutte le classi deputate alla gestione dell’interfaccia grafica.

 

Commenti

I commenti sono delle stringhe di testo che vegono utilizzate per spiegare il codice che si sta scrivendo. Quando scriviamo un programma non è detto che lo utilizzeremo solo noi, può darsi che quel codice vada in mano ad un collega. È bene quindi commentarlo per far capire a chi legge il codice (anche a noi stessi, se lo rileggiamo dopo un po’ di tempo!) cosa abbiamo fatto.I commenti in java si fanno in due modi:

 

// commento su singola riga

/*

 * commento su più righe

 * lo utilizziamo quando dobbiamo spiegare qualcosa di più elaborato

 */
Leggi tutto

Cerca...