Liigu peamise sisu juurde

Tõeväärtused ja loogikatehted

Sissejuhatus

Tõeväärtus (boolean) on primitiivne andmetüüp, millel saab olla vaid kaks väärtust: tõene (true) ja väär (false). See on põhiline andmetüüp loogiliste väidete ja tingimuste esitamiseks programmis.

Väärtustamine

Kõige lihtsam viis on omistada otse kas true või false väärtus:

boolean a = true;
boolean b = false;

Võrdlused annavad ka tulemuseks kas true või false:

int age = 20;
boolean isAdult = age >= 18; // true
boolean isTeenager = age < 20; // false
boolean isExactly20 = age == 20; // true

Sellest tulenevalt võib ka tingimusi kokku aheldada, et tekitada keerukam avaldis:

int temperature = 5;
boolean isWetAndCold = temperature > 0 && temperature < 10; // returns true if temperature is between 0 and 10
info

Ahvatlev oleks kirjutada näiteks boolean a = 10 < x < 20, et näha, kas x on 10 ja 20 vahel. Sedasi töötab arvude võrdlemine näiteks Pythonis, kuid Javas see aga ei tööta, sest iga < operaator saab ainult korraga kontrollida kahte väärtust. Õige on kirjutada boolean a = 10 < x && x < 20

Põhioperatsioonid

Loogikatehete jaoks on Javas kolm operaatorit:

OperaatorNimiKirjeldus Näide 
&&JA (AND)Tõene, kui mõlemad pooled on tõesed true && true on true
||VÕI (OR)Tõene, kui vähemalt üks pool on tõenetrue || false on true
!EI (NOT)Pöörab väärtuse vastupidiseks !true on false

Vastav tõeväärtustabel:

PQP && QP || Q!P
truetruetruetruefalse
truefalsefalsetruefalse
falsetruefalsetruetrue
falsefalsefalsefalsetrue

Näited:

boolean hasTicket = true;
boolean hasID = false;

// AND - Both sides have to be true
boolean canEnter = hasTicket && hasID;
System.out.println(canEnter); // false

// OR - At least one side has to be true
boolean hasDocuments = hasTicket || hasID;
System.out.println(hasDocuments); // true

// NOT - inverts value
boolean needsTicket = !hasTicket;
System.out.println(needsTicket); // false

Loogikatehete järjekord

Loogikatehete puhul kasutatakse short-circuit evaluation meetodit ehk järgnev avaldis valideeritakse siis, kui esimene seda lubab.
&& operaatori puhul tähendab see seda, et kui eelnev tingimus on väär, siis järgmist tööle ei panda:

boolean result = false && someExpensiveMethod();

// someExpensiveMethod is never executed because the statement before it is false

See tuleb kasuks näiteks olukorras, kus mingil muutujaga on vaja läbi viia mingi tegevus, kuid selle väärtus võib parasjagu ka null olla:

String text = null;

// Correct - text.length() is not executed because text != null resulted in false
if (text != null && text.length() > 0) {
System.out.println("Text is not empty");
}

// Error - null does not have .length() method
if (text.length() > 0 && text != null) {
System.out.println("Text is not empty");
}

|| puhul on vastupidi. Kui eelmisega oli, et false puhul ei panda järgnevaid tööle, siis ||-iga ei panda järgnevaid tööle, kui eelneva tulemus on true.

boolean result = true || someExpensiveMethod();

// someExpensiveMethod() is never executed because the statement before it is true

See tuleb kasuks olukorras, kus näiteks üks tingimus peaks trumpama teist üle:

int age = 25;

// If user is an admin then don't impose age verification
if (isAdmin || age >= 18) {
// ...
}

short-circuit evaluation käitumist on võimalik vältida, kui kasutada topelt märkide asemel ühekordseid (& ja |). Sel juhul mõlemad operandide pooled käivitatakse. Praktikas kasutatakse loogiliste avaldiste puhul peaaegu alati && ja ||, kuna need on ohutumad, selgemad ning väldivad tarbetuid arvutusi ja võimalikke vigu.

Stiilireeglid

Tõeväärtustega tegeledes kehtivad ka teatud stiilireeglid.

Esmalt, tingimuslauses tõeväärtusi kontrollides vältige true või false-ga võrdlemist:

// Bad style, avoid writing like this
if (isStudent == true) {
System.out.println("Is a student");
}

if (hasLicense == false) {
System.out.println("No license");
}

// Correct style
if (isStudent) {
System.out.println("Is a student");
}

if (!hasLicense) {
System.out.println("No license");
}

Sarnane reegel kehtib ka meetodite puhul, mis tagastavad tõeväärtust. Loogikaavaldiste juhul ei pea eraldi true või false tagastama:

// Bad style, explicitly returning true or false
public boolean isEven(int number) {
if (number % 2 == 0) {
return true;
} else {
return false;
}
}

// Correct style - == evaluates to true or false anyways
public boolean isEven(int number) {
return number % 2 == 0;
}

Tõeväärtuste nimetused peaksid olema küsimused, millele saab vastata jaatavalt või eitavalt. Näiteks:

  • isActive, hasPermission, canEdit
  • isEmpty, isValid, isComplete
  • shouldRetry, willExpire, needsUpdate

Boolean wrapper klass

Nagu teiste primitiivsete tüüpide puhul, on ka boolean jaoks olemas seda tähistav klass - Boolean. Wrapper klassidest on pikemalt juttu siin, seega siinkohal keskendutakse ainult Boolean klassi spetsiifikale.

Praktikas kasutatakse seda ainult juhtudel, kus ei ole võimalik primitiive kasutada (nt. kollektsioonid) või null-väärtust on vaja võimalik kasutada. Antud olukorras rakenduvad ka teadaolevad riskid, näiteks NullPointerException-i oht.

Boolean klass võimaldab kasutada ka parseBoolean meetodit ehk sõne tõeväärtuseks teisendamine:

boolean b1 = Boolean.parseBoolean("true");    // true
boolean b2 = Boolean.parseBoolean("TRUE"); // true (case-insensitive)
boolean b3 = Boolean.parseBoolean("false"); // false
boolean b4 = Boolean.parseBoolean("yes"); // false (only "true" gives true!)