Il tipo boolean

È un tipo di dati i cui unici valori possibili sono vero e falso.

Servono per memorizzare i valori di condizioni.


A cosa serve?

Vediamo l'esempio del verificare la presenza di valori negativi.

class Presenza {
  public static void main(String args[]) {
    int f=0, x;

    String presenza;
    presenza="no";

    for(x=0; x<=10; x++) {
      f=x*x-10*x+2;

      if(f<0)
        presenza="si";
    }

    System.out.println(presenza);
  }
}

La stringa presenza poteva assumere solo due valori possibili.

Questi due valori indicano se una cosa è vera oppure falsa (la presenza di valori negativi)

In base alla condizione, potevo poi fare:

  if(presenza=="si")
    ...

Variabili booleane

La variabile stringa del programma di sopra assumeva solo due valori

Questi due valori dicevano se qualcosa è vero o falso.

Esiste un tipo di dato fatto apposta per questo tipo di valori: boolean

Una variabile boolean può assumere soltanto due valori: vero o falso

class PrimoBool {
  public static void main(String args[]) {
    boolean b;

    b=true;
    System.out.println(b);

    b=false;
    System.out.println(b);
  }
}

Presenza, con boolean

La presenza o meno può essere vera o no, quindi posso usare un boolean.

Il boolean dice al risposta alla domanda "è stato trovato un valore negativo finora?"

La risposta può essere solo "true" (vero) oppure "false" (falso)

class Presenza {
  public static void main(String args[]) {
    int f=0, x;

    boolean presenza;
    presenza=false;

    for(x=0; x<=10; x++) {
      f=x*x-10*x+2;

      if(f<0)
        presenza=true;
    }

    if(presenza)
      System.out.println("si");
    else
      System.out.println("no");
  }
}

Non dovrebbe essere...?

Perchè if(presenza)?

Non dovrebbe essere if(presenza==true)?

Le condizioni sono espressioni, ma il valore calcolato è true oppure false


Valori booleani

Espressioni:

espressioni intere
calcolano un valore intero (es. a+2)
espressioni reali
calcolano un valore reale (es. a+2.0)
espressioni booleane
calcolano un valore booleano, ossia un valore che può essere solo vero o falso (es. a==2)

In altre parole, a==0 è una espressione come tutte le altre

La cosa particolare è che il valore di ritorno è un boolean


Condizioni

if(condizione) ...
for(...; condizione; ...)
while(condizione)

Quando scrivo condizione intendo una espressione che ritorna un valore booleano.


Espressioni booleane

Tutti i confronti (es. a==2, a+2.0>3.9 ecc.) sono espressioni booleane (semplici)

Se ho una espressione booleana e, allora !e è una espressione booleana
(il valore è true se e solo se e è false, e viceversa)

Se ho due espressioni booleane e1 ed e2, allora e1||e2 ed e1&&e2 sono espressioni booleane.

Anche true, false, e le variabili booleane si possono usare come espressioni booleane semplici.


Esempi di espressioni booleane

Questo programma contiene qualche esempio.

class Esempi {
  public static void main(String args[]) {
    boolean a, b;
    int x=1;

    a=true;
    b=(x==1);

    a=(a||b);

    b=!((a&&b)||(x==2));

    System.out.println(a);
  }
}

Operatori booleani

||  && !

Sono operatori booleani: dato un valore (!) o due valori (|| ed &&) trovano un nuovo valore


Paragone con gli operatori interi

+ - * /

Se ho due espressioni intere e1 ed e2, allora posso scrivere e1 + e2.

Viene valutata e1, poi e2, e cosí si trovano due numeri.

Dato che ho l'operatore +, li sommo.

|| & &

Se ho due espressioni booleane e1 ed e2, allora posso scrivere e1 || e2.

Viene valutata e1, poi e2, e cosí si trovano due valori booleani (ossia due valori tre true e false

Dato che ho l'operatore ||, il valore calcolato è l'or (vero se almeno uno dei due valori è vero.


Cosa fa il not !

Scrivere !e è il contrario di e

valore di e valore di !e
false true
true false

Cosa fa l'or ||

La condizione composta è vera se lo è almeno una delle due

valore di e1 valore di e2 valore di e1 || e2
false false false
false true true
true false true
true true true

Cosa fa l'and &&

La condizione composta è vera se lo sono tutte e due le condizioni che la compongono.

valore di e1 valore di e2 valore di e1 && e2
false false false
false true false
true false false
true true true

Perchè si usa?

Possiamo realizzare delle condizioni anche molto complicate:

(a >= 2) && (a <= 5)
è una condizione che è vera se la variabile a è compresa fra 2 e 5
(a==0) || (a==10)
è vera se a vale 0 oppure vale 10
(a!=0) || ((b==1) && (b==-1))
è vera se a è diverso da zero, oppure se a vale zero e poi il valore assoluto di b è 1

E le variabili booleane?

Permettono di memorizzare il risultato di una condizione, e poi di usarlo anche molto dopo.

  calcolo se ci sono valori negativi
  (il risultato va in presenza)

  altri calcoli

  stampo tutto alla fine

Gli altri calcoli potrebbero aver bisogno di sapere se ci sono valori negativi o no: gli basta usare presenza


Booleani come valori di ritorno

Un metodo può ritornare un valore booleano.

Esempio: il metodo contains della classe Rectangle vede se un punto si trova all'interno del rettangolo.

import java.awt.*;

class Dentro {
  public static void main(String args[]) {
    Rectangle r;
    r=new Rectangle();

    r.setBounds(10,10,20,20);

    Point p;
    p=new Point();

    p.move(20,15);

    System.out.println(r.contains(p));
  }
}

Uso di un valore booleano

Si può stampare

Si può usare come condizione

Si può usare all'interno di una condizione più complessa.

Si può memorizzare in una variabile booleana

import java.awt.*;

class Usi {
  public static void main(String args[]) {
    Rectangle r;
    r=new Rectangle();
    r.setBounds(10,10,20,20);
    Point p;
    p=new Point();
    p.move(20,15);

    boolean b;
    b=r.contains(p);

    if( (p.x>0) && (r.contains(p)) ) 
      System.out.println("OK");
    else 
      while(b && !r.contains(p))
         p.x=p.x+1;
  }
}

Nuovo metodo che torna un valore booleano

Creare una classe che ha le stesse componenti di Rectangle ma in più un metodo che prende due punti e vede se il segmento compreso fra i due punti si trova tutto dentro il rettangolo.

Suggerimento?


Suggerimento

Il segmento si trova tutto dentro il rettangolo se e solo se entrambi i punti si trovano all'interno del rettangolo.


Implementazione del metodo

Il metodo prende due punti e torna un valore booleano:

class RectSegm {
  ...

  boolean tuttoInterno(Point p, Point q) {
    return ...;
  }
}

Calcolo del valore di ritorno

  se tutti e due i punti sono nel rettangolo
    ritorna true
  altrimenti
    ritorna false

Si traduce immediatamente in codice:

class RectSegm {
  ...

  boolean tuttoInterno(Point p, Point q) {
    if(this.contains(p) && this.contains(q))
      return true;
    else
      return false;
  }
}

Soluzione alternativa

Devo ritornare un valore booleano

Questo valore deve essere vero se e solo se la espressione this.contains(p) && this.contains(q) è vera.

Ritorno il valore di questa espressione

class RectSegm {
  ...

  boolean tuttoInterno(Point p, Point q) {
    return (this.contains(p) && this.contains(q));
  }
}

Espressioni e valori booleani

Esempio di invocazione del metodo:

import java.awt.*;

class ProvaRectSegm {
  public static void main(String args[]) {
    int x;

    RectSegm r;
    r=new RectSegm();
    r.setBounds(10,10,20,20);

    Point a, b;
    a=new Point();
    a.move(11,11);
    b=new Point();
    b.move(15,12);

    if( (a.x==0) && r.tuttoInterno(a,b) )
      System.out.println("No");
    else
      for(x=a.x; x<b.x; x=x+1)
        System.out.println(x);
  }
}

Metodo del risultato parziale

Il programma per la presenza di valori negativi usa il metodo del risultato parziale:

    presenza=false;

    for(x=0; x<=10; x++) {
      f=x*x-10*x+2;

      if(f<0)
        presenza=true;
    }

All'inizio, presenza dice se ci sono elementi negativi in un insieme di 0 interi.

Ad ogni passo, si considera un nuovo elemento.


Operatore associativo

Con questo metodo, posso vedere se ci sono negativi in un insieme di n interi.

Come condizione booleana:

(a1<0) || (a2<0) || ... (an<0)

Uso il fatto che || è associativo:

(a1<0) || ... || (ai<0) = 
((a1<0) || ... || (ai-1<0) ) || (ai<0)

L'elemento neutro è false

Viene esattamente lo stesso ciclo di sopra.

Quindi: in effetti sto usando il metodo del risultato parziale per calcolare il risultato di un operatore associativo.