Operatorii logici

Exista multe situatii in care este nevoie in cod de mai multe verificari in acelasi timp. De exemplu daca vrem sa verificam daca o nota este valida, adica intre 1 si 10 am putea avea nevoie sa verificam ca este mai mare ca 0 si mai mica decat 11. Sau intr-o alta situatie daca am avea o zi din saptamana pentru a afla daca e zi de weekend am verifica daca ziua respectiva este egala cu SAMBATA sau DUMINICA.

Pentru astfel de situatii se folosesc operatorii logici: && si ||. Primul este SI(AND) logic, al doilea este SAU(OR) logic. Comportamentul lor este descris de urmatoarele tabele:

AND false true
false false false
true false true
OR false true
false false true
true true true

Traducand aceste doua tabele in cod am putea avea urmatorul tabel considerand doua expresii booleene expA si expB:

expA expB expA && expB expA || expB
false false false false
true false false true
false true false true
true true true true

Pe langa acesti operatori logici care implica existenta a doi operanzi mai exista si un operator unar de negare logica (!). Acesta necesita un singur singur operand si ii neaga valoarea logica. Asta inseamna ca:

expresie !expresie
true false
false true

De exemplu daca vrem sa verificam daca o nota este valida (in intervalul 1-10) metoda de verificare ar putea arata asa:


  public boolean esteNotaValida(int nota) {
    if (nota >= 1 && nota <= 10) { // daca nota e mai mare sau egala cu SI mai mica sau egala cu 10 
      return true;                 // returneaza true
    }
    return false;                  // daca am ajuns aici inseamna ca nu am returnat true, deci returneaza false
  }
}

Aceeasi metoda se poate scrie si folosind operatorul de SAU logic, chiar daca nu e recomandabil pentru ca face codul mai greu de inteles. In traducere ne intrebam daca nota e mai mica decat 1 SAU mai mare ca 10, si in acest caz returnam false.


  public boolean esteNotaValida(int nota) {
    if (nota < 1 || nota > 10) {   // daca nota e mai mica decat 1 SAU mai mare ca 10 
      return false;                 // returneaza false
    }
    return true;                  // daca am ajuns aici inseamna ca nu am returnat false, deci returneaza true
  }
}

Alegerea operatorului potrivit depinde de complexitatea expresiei booleene. In general trebuie sa incercati sa folositi exact operatorul care rezulta din descrierea verbala a problemei. (Ex: daca nota e mai mare ca 0 SI mai mica decat 11).

Pentru a exemplifica folosirea operatorului de negare (!) am putea modifica aceeasi metoda de mai sus cu mentiunea ca nici aceasta nu e o versiune mai buna, o folosim doar in scop demonstrativ. Se observa ca folosim parantezele pentru a nega rezultatul unei intregi expresii. Traducand in cuvinte am spune "Daca NU se intampla ca nota sa fie mai mica decat 1 SAU mai mare ca 10..."


  public boolean esteNotaValida(int nota) {
    if (!(nota < 1 || nota > 10)) {  // daca nota NU e mai mica decat 1 SAU mai mare ca 10 
      return true;                   // returneaza true
    }
    return false;                    // daca am ajuns aici inseamna ca nu am returnat true, deci returneaza false
  }
}

Acesti operatori se mai numesc de scurtcircuitare si au o caracteristica speciala fata de oricare alti operatori. Daca privim cu atentie tabelul de adevar pentru SI observam faptul ca daca unul din operanzi este false intotdeauna rezultatul expresiei va fi false. De asemenea, pentru SAU daca unul din operanzi e true atunci intreaga expresie va fi true. Bazandu-ne pe aceste observatii avand codul:


    if (nota >= 1 && nota <= 10) {
    ...    

am putea spune ca daca nota este de exemplu 0 dupa evaluarea expresiei nota >= 1 care ne da false nu mai are sens sa evaluam si a doua parte a expresiei, (nota >= 10) pentru ca stim deja ca rezultatul va fi false. Java foloseste acest principiu si intr-adevar nu va mai evalua al doilea operand, optimizand executia codului. Totusi aceasta optimizare ar putea duce la probleme in cazul in care al doilea operand ar fi un apel de metoda care returneaza un boolean, dar despre asta vom vorbi ulterior. Acelasi comportament il are si operatorul ||, dar in sens invers, daca primul operand este true intreaga expresie este true, deci nu va mai fi evaluata in continuare.

Este momentul sa arati ce ai invatat. Rezolva testul TR9 pentru a-ti verifica cunostintele dobandite pana acum.