Come si chiama Java ?, si chiama operator e cosa fa?


161

Lavoro con Java da un paio d'anni, ma fino a poco tempo fa non ho riscontrato questo costrutto:

int count = isHere ? getHereCount(index) : getAwayCount(index);

Questa è probabilmente una domanda molto semplice, ma qualcuno può spiegarlo? Come lo leggo? Sono abbastanza sicuro di sapere come funziona.

  • se isHereè vero, getHereCount()si chiama,
  • se è chiamato isHerefalso getAwayCount().

Corretta? Come si chiama questo costrutto?


2
Vedi anche stackoverflow.com/questions/795286/what-does-do-in-c per la versione C ++ di questa domanda (posta proprio ieri, in effetti).
Michael Myers

2
Tieni presente che il mondo C / C ++ / Java è abbastanza equamente diviso tra persone che pensano che sia brutto e confuso e lo eviteranno come la peste, e le persone che pensano che non puoi davvero affermare di conoscere C, C ++ o Java se tu non posso riconoscerlo e usarlo senza fermarti a pensare.
Paul Tomblin,

3
È generalmente considerato in cattiva forma in Java usarlo oltre il più chiaro e semplice dei casi. Se ti ritrovi a nidificarli, sei una via d'uscita. D'altra parte, nella cultura C dove il codice veloce e intelligente è valutato al di sopra della chiarezza, è considerato accettabile.
Yishai,

17
answer_to_question = (detect_operator)? (social_acceptance): (condescending_finger_wag)
Dan,

È possibile fare riferimento a questa risorsa per ulteriori informazioni.
Shiva,

Risposte:


189

Sì, è una forma abbreviata di

int count;
if (isHere)
    count = getHereCount(index);
else
    count = getAwayCount(index);

Si chiama operatore condizionale . Molte persone (erroneamente) lo chiamano operatore ternario , perché è l'unico operatore ternario (a tre argomenti) in Java, C, C ++ e probabilmente in molte altre lingue. Ma in teoria potrebbe esserci un altro operatore ternario, mentre può esserci solo un operatore condizionale .

Il nome ufficiale è indicato nella specifica del linguaggio Java :

§15.25 Operatore condizionale? :

L'operatore condizionale ? :utilizza il valore booleano di un'espressione per decidere quale delle altre due espressioni deve essere valutata.

Si noti che entrambi i rami devono condurre a metodi con valori restituiti:

È un errore in fase di compilazione per la seconda o la terza espressione di operando come invocazione di un metodo vuoto.

In effetti, secondo la grammatica delle dichiarazioni di espressione ( §14.8 ), non è consentito che un'espressione condizionale appaia in qualsiasi contesto in cui potrebbe apparire un'invocazione di un metodo vuoto.

Quindi, se doSomething()e doSomethingElse()sono metodi nulli, non è possibile comprimere questo:

if (someBool)
    doSomething();
else
    doSomethingElse();

in questo:

someBool ? doSomething() : doSomethingElse();

Parole semplici:

booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse 

Non capisco cosa fa di sbagliato quello in basso. Ti credo e tutto il resto. Mi sembra lo stesso dell'originale. È perché chiamano semplicemente un'altra funzione che può o non può restituire un valore e consentire l'esecuzione del codice successivo impostato?
johnny,

8
Suppongo che doSomething () e doSomethingElse () siano metodi nulli. Quello che dice l'ultimo bit della specifica è che l'operatore ternario deve restituire un valore, quindi nessuno degli operandi può essere un metodo nullo.
Michael Myers

Dice un po 'di più. Dice che l'operatore condizionale non è autorizzato dove appare un metodo vuoto. Quindi, ad esempio, le seguenti dichiarazioni: VALID: String x = (false)? "X": "Y"; NON VALIDO: (falso)? "X": "Y";
kenj0418

4
Non è errato chiamarlo "operatore ternario", così come non è errato (nel 2016) riferirsi a Obama come "il Presidente", anche se è possibile che ci saranno altri presidenti in futuro.
Dawood ibn Kareem,

2
@DawoodibnKareem Penso che Michael abbia deliberatamente incluso thenel corsivo di the ternary operator, ed è quello che intende è errato, non ternary operatorè errato. L' operatore ternario implica che, come dice Michael, è l'unico, che a sua volta potrebbe indurre a pensare non ci possono essere altri operatori ternari, che è quello che Michael sta dicendo è erronea, e io sono d'accordo, si sarebbe essere un'ipotesi errata.
Ghoti and Chips il

32

Altri hanno risposto a questo in misura ragionevole, ma spesso con il nome di "operatore ternario".

Essendo il pedante che sono, vorrei chiarire che il nome dell'operatore è l'operatore condizionale o "operatore condizionale?:". È un operatore ternario (in quanto ha tre operandi) e al momento sembra essere l'unico operatore ternario in Java.

Tuttavia, la specifica è abbastanza chiara che il suo nome è l'operatore condizionale o "operatore condizionale?:" Per essere assolutamente inequivocabile. Penso che sia più chiaro chiamarlo con quel nome, in quanto indica il comportamento dell'operatore in una certa misura (valutazione di una condizione) piuttosto che solo quanti operandi ha.


3
Questa risposta è tecnicamente corretta. Tuttavia, poiché esiste un solo operatore ternario, spesso viene visualizzato come operatore ternario. Anche se questo nome non trasmette il significato completo dell'operatore, è un nome che è rimasto bloccato. Se menzioni il nome "operatore ternario", i programmatori sanno di cosa stai parlando. Le specifiche che menzioni si riferiscono anche a questo operatore come "Condizionale ternaria" che sembra più informativo. java.sun.com/docs/books/jls/third_edition/html/…
Gary

17
Penso solo che valga la pena chiamare qualcosa con il suo nome definito. In particolare, se Java ottiene un altro operatore ternario, le persone che usano il termine "operatore condizionale" saranno comunque corrette e inequivocabili, a differenza di quelli che dicono semplicemente "operatore ternario". Sì, la frase "operatore ternario" è rimasta bloccata - la mia risposta è parte di uno sforzo per "sbloccarlo", proprio mentre provo a correggere l'affermazione che "gli oggetti vengono passati per riferimento".
Jon Skeet,

1
Posso indirizzarti a questa pagina da Oracle che parla di tre "operatori condizionali" ma di un solo "operatore ternario"? Se vuoi chiarire quale operatore intendi, probabilmente è meglio usare il nome che la maggior parte delle persone usa. (Sì, lo so che mi presenterò alla festa proprio mentre l'ospite sta lavando l'ultimo piatto).
Dawood ibn Kareem,

@DavidWallace: usando "operatore condizionale?:" È meglio, IMO - modificherà per chiarire questo. Ma penso che valga la pena persuadere le persone a usare il nome reale dell'operatore piuttosto che concentrarsi su un aspetto di esso (quanti operandi ha) che non ha nulla a che fare con il suo comportamento. (Inoltre, non è raro che le esercitazioni siano meno precise della specifica, che chiama &&il condizionale e l'operatore e ||l'operatore o condizionale, ma usa solo "l'operatore condizionale" per ?:.
Jon Skeet

Non lo so. Se qualcuno mi dice "operatore condizionale" per me, non sarò sicuro di cosa significhino. Da dove vengo (l'estremità opposta del mondo da te) la gente non la chiama così. Se dicono "operatore ternario" o "operatore hook", allora capisco. Ammiro la tua ambizione, voler cambiare il modo in cui le persone parlano. Se qualcuno può farlo, sei tu. Ma non offro molta speranza né vedo molto punto.
Dawood ibn Kareem,

17

Secondo le specifiche Sun Java , si chiama Operatore condizionale. Vedi sezione 15.25. Hai ragione su cosa fa.

L'operatore condizionale? : utilizza il valore booleano di un'espressione per decidere quale delle altre due espressioni deve essere valutata.

L'operatore condizionale è sintatticamente associativo-destra (raggruppa da destra a sinistra), quindi a? B: c? D: e? F: g significa lo stesso di a? B: (c? D: (e? F : g)).

ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression

L'operatore condizionale ha tre espressioni di operando; ? appare tra la prima e la seconda espressione e: appare tra la seconda e la terza espressione.

La prima espressione deve essere di tipo booleano o booleano, altrimenti si verifica un errore di compilazione.


5
int count = isHere ? getHereCount(index) : getAwayCount(index);

si intende :

if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

5

Non esattamente corretto, per essere precisi:

  1. se isHere è vero, viene restituito il risultato di getHereCount ()
  2. altrimenti viene restituito il risultato di getAwayCount ()

Quel "ritorno" è molto importante. Significa che i metodi devono restituire un valore e quel valore deve essere assegnato da qualche parte.

Inoltre, non è esattamente sintatticamente equivalente alla versione if-else. Per esempio:

String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;

Se codificato con if-else si otterrà sempre più bytecode.


Credo che javac sia libero di generare lo stesso bytecode. Anche se hai ragione sul fatto che ci sono casi d'angolo oscuri in cui non sono equivalenti.
Tom Hawtin - tackline il

Sì, naturalmente. Per me, il vero merito dell'operatore condizionale è l'esempio che ho dato. L'alternativa è: // sussulto !! String temp = str1; if (check) temp + = str2; altrimenti temp + = str3; temp + = str4; temperatura di ritorno; o codifica a mano l'operazione di aggiunta StringBuilder. Il primo soffre di gravi problemi di efficienza mentre il secondo è troppo dettagliato ed è uno sforzo scrupoloso senza molto guadagno.
RichN

4

Ternario, condizionale; pomodoro, pomodoro. Ciò che è veramente prezioso per l'inizializzazione variabile. Se (come me) ti piace inizializzare le variabili in cui sono definite, l'operatore ternario condizionale (perché è entrambe le cose) ti consente di farlo nei casi in cui c'è una condizionalità sul suo valore. Particolarmente notevole negli ultimi campi, ma utile anche altrove.

per esempio:

public class Foo {
    final double    value;

    public Foo(boolean positive, double value) {
        this.value = positive ? value : -value;
    }
}

Senza quell'operatore - con qualunque nome - dovresti rendere il campo non definitivo o scrivere una funzione semplicemente per inizializzarlo. In realtà, non è giusto: può ancora essere inizializzato usando if / else, almeno in Java. Ma trovo questo più pulito.



3

Questo costrutto si chiama Operatore ternario in Informatica e tecniche di programmazione.
E Wikipedia suggerisce la seguente spiegazione:

In informatica, un operatore ternario (a volte erroneamente chiamato un operatore terziario) è un operatore che prende tre argomenti. Gli argomenti e il risultato possono essere di diversi tipi. Molti linguaggi di programmazione che usano la sintassi di tipo C presentano un operatore ternario,?:, Che definisce un'espressione condizionale.

Non solo in Java, questa sintassi è disponibile anche in PHP, Objective-C.

Nel seguente link fornisce la seguente spiegazione, che è abbastanza buona per capirla:

Un operatore ternario è un'operazione che opera su 3 ingressi. È un collegamento per un'istruzione if-else ed è anche noto come operatore condizionale.

In Perl / PHP funziona come:
boolean_condition ? true_value : false_value

In C / C ++ funziona come:
logical expression ? action for true : action for false

Questo potrebbe essere leggibile per alcune condizioni logiche che non sono troppo complesse, altrimenti è meglio usare il blocco If-Else con la combinazione prevista di logica condizionale.

Possiamo semplificare i blocchi If-Else con questo operatore Ternary per una riga di istruzione del codice.
Per esempio:

if ( car.isStarted() ) {
     car.goForward();
} else {
     car.startTheEngine();
}

Potrebbe essere uguale al seguente:

( car.isStarted() ) ? car.goForward() : car.startTheEngine();

Quindi, se ci riferiamo alla tua affermazione:

int count = isHere ? getHereCount(index) : getAwayCount(index);

In realtà è l'equivalente del 100% del seguente blocco If-Else :

int count;
if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

Questo è tutto!
Spero che questo sia stato utile per qualcuno!
Saluti!



2

Il suo operatore ternario (? :)

The ternary operator is an operator that takes three arguments. The first 
argument is a comparison argument, the second is the result upon a true 
comparison, and the third is the result upon a false comparison.

1

Potresti essere interessato a una proposta per alcuni nuovi operatori simili all'operatore condizionale. Gli operatori null-safe abiliteranno il codice in questo modo:

String s = mayBeNull?.toString() ?: "null";

Sarebbe particolarmente conveniente in caso di auto-unboxing.

Integer ival = ...;  // may be null
int i = ival ?: -1;  // no NPE from unboxing

È stato selezionato per ulteriori considerazioni in "Project Coin" di JDK 7.


Quell'operatore non è uno dei miei preferiti da Project Coin. Utilità limitata, non intuitiva da leggere, e semplicemente brutta come tutti escono. Forse sarebbe cresciuto su di me, però.
Michael Myers

Non sono neanche un grande fan, in realtà. È una proposta di Neal Gafter e tende a vedere le cose in modo molto diverso dal normale programmatore Java, che tende a vedere le cose in modo diverso dal tuo medio essere umano. L'unico posto in cui mi potrebbe piacere un piccolo aiuto con i null è in un ciclo foreach, verificando se l'iterabile è null e l'auto-unboxing.
Erickson,

IIRC <Neal non lo ha proposto. Lo ha appena usato come un semplice esempio di come scrivere una proposta. Maggiori dettagli sull'archivio della mailing list delle monete del progetto.
Tom Hawtin - tackline il

Ho appena letto l'introduzione della proposta e hai ragione. È Stephen Colebourne di Joda e la fama di "non c'è Java 7".
Erickson,

1

In realtà possono essere necessari più di 3 argomenti. Ad esempio, se vogliamo verificare se un numero è positivo, negativo o zero, possiamo farlo:

String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";

che è meglio che usare if, else if, else.


0

È l'operatore condizionale, ed è più di un semplice modo conciso di scrivere if.

Poiché è un'espressione che restituisce un valore, può essere utilizzata come parte di altre espressioni.


0

Sì hai ragione. ?: viene generalmente chiamato "operatore ternario", spesso definito semplicemente "operatore ternario". È una versione abbreviata dello standard if / else condizionale.

Operatore condizionale ternario


0

Mi piace molto questo operatore, ma il lettore dovrebbe essere preso in considerazione.

Devi sempre bilanciare la compattezza del codice con il tempo impiegato a leggerlo, e in quanto presenta alcuni difetti piuttosto gravi.

Prima di tutto, c'è il caso del richiedente originale. Ha appena trascorso un'ora a postare e leggere le risposte. Quanto tempo avrebbe impiegato l'autore a scrivere ogni?: Come se / quindi nel corso di tutta la sua vita. Non un'ora per essere sicuri.

In secondo luogo, nei linguaggi di tipo C, hai l'abitudine di sapere semplicemente che i condizionali sono la prima cosa in linea. Ho notato questo quando stavo usando Ruby e ho trovato linee come:

callMethodWhatever(Long + Expression + with + syntax) if conditional

Se fossi un utente di Ruby da molto tempo, probabilmente non avrei avuto problemi con questa linea, ma proveniente da C, quando vedi "callMethodWhatever" come la prima cosa nella riga, ti aspetti che venga eseguito. Il?: È meno criptico, ma ancora abbastanza insolito da buttare via un lettore.

Il vantaggio, tuttavia, è una sensazione davvero interessante nella tua pancia quando puoi scrivere un'istruzione if a 3 righe nello spazio di 1 delle righe. Non posso negarlo :) Ma onestamente, non necessariamente più leggibile dal 90% delle persone là fuori semplicemente per la sua "rarità".

Quando si tratta veramente di un incarico basato su valori booleani e valori, non ho alcun problema, ma può essere facilmente abusato.


0

Le espressioni condizionali hanno uno stile completamente diverso, senza esplicito se nell'istruzione.

La sintassi è: espressione booleana? espressione1: espressione2;

Il risultato di questa espressione condizionale è

espressione1 se espressione booleana è vera;

altrimenti il ​​risultato è expression2.

Supponiamo di voler assegnare il numero maggiore di variabile num1 e num2 a max. Puoi semplicemente scrivere un'istruzione usando l'espressione condizionale: max = (num1> num2)? num1: num2;

Nota: i simboli? e: appaiono insieme in un'espressione condizionale. Formano un operatore condizionale e anche chiamato un operatore ternario perché utilizza tre operandi. È l'unico operatore ternario in Java.

citato da: Intro to Java Programming 10th edition di Y. Daniel Liang pagina 126 - 127

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.