2016-06-01 14 views
0

Ich versuche, einmal zu vereinfachen und für alle, eine gemeinsame Bedingung:java ternärer Operator und lazy evaluation

public static void main(String[] args) 
{ 
    boolean a = true; 
    boolean b = false; 
    boolean c = true; 

    boolean t1 = (a && b) || (!a && c); 
    boolean t2 = a ? b : c; 

    System.out.println(t1); 
    System.out.println(t2); 
} 

wo offensichtlich t1 und t2 gleichwertig ist.

Gibt es eine Möglichkeit, die Bedingung mit Operatorrangfolge auszudrücken, ohne den ternären Operator zu verwenden und a nur einmal auszuwerten?

Dank


reale Welt Beispiel:

if(execution.isActive() ? !Objects.equals(sourceStep, currentStep) : sourceStep != null) 
{ 
    throw new IllegalStateException("current action is not allowed to be executed"); 
} 

wo execution.isActive() eine teuere Operation ist.

Für meinen Geschmack ist dies überhaupt nicht lesbar ... Ich muss aufhören und denke, es ist nicht sofort.

Meine Frage ist über Lesbarkeit vs Effizienz.

+1

Warum nicht den ternären Operator verwenden? Es ist einfacher als der andere Ausdruck und auch einfacher als eine if-Anweisung. – Eran

+0

Ist das Hausaufgaben? – Kayaman

+0

@Eran, weil es schwierig zu lesen ist, tendiere ich dazu, ternäre Operatoren zu vermeiden, wenn möglich –

Antwort

1

Im wirklichen Leben, wenn ein tatsächlich das Ergebnis eines teuren Anrufs war, würde ich es nur zu einer Variablen extrahieren.

Änderung dieser:

boolean t1 = (expensiveCall() && b) || (!expensiveCall() && c); 

dazu:

boolean result = expensiveCall(); 
boolean t1 = (result && b) || (!result && c); 

Aber abgesehen davon: Ich habe nichts falsch mit der Verwendung des ternären Operator sehen.

1

Wenn ich den Code leichter lesen möchten, würde ich lieber tun, wie folgt:

private boolean isIllegalAction(execution,sourceStep,currentStep){ 
     return execution.isActive() ? !Objects.equals(sourceStep, currentStep) : sourceStep != null; 
    } 

    if(isIllegalAction(...)){ 
     //do something 
    } 
1

Meine Frage bezieht sich auf die Lesbarkeit vs Effizienz

Sehr gut.

  • Lesbarkeit. Es gibt viele Situationen, in denen In-Lining-Wenn-Dann-Else-Blöcke zu verbesserter Lesbarkeit des Codes führen können.

Bedenken Sie:

int result = (myObject.isCompleted()) 
     ? myObject.getStandardError() 
     : myObject.computeStandardError().getStandardError(); 

... im Vergleich zu:

int result = 0; 
if (myObject.isCompleted()) { 
    result = myObject.getStandardError(); 
} 
else { 
    result = myObject.computeStandardError().getStandardError(); 
} 

Ich würde sagen, die in ausgekleideten if-then-else viel besser lesbar ist, würden Sie nicht?

  • Effizienz. Der Unterschied in der Verarbeitungszeit zwischen einem logisch äquivalenten Inline-If-Then-Else-Block und einem If-Then-Else-Block (falls vorhanden) ist fast sicher verschwindend klein und in realen Anwendungen nicht wichtig.Daher wählen Sie die Struktur, die die beste Lesbarkeit bietet. In vielen Fällen ist dies der ternäre Operator ... aber nicht alle Fälle.
+0

Kein Zweifel, wenn es eine direkte Zuweisung ist, und ich stimme Ihnen zu, das ist das Beste für die meisten Fälle. Aber für verkettete Auswertung (siehe mein Beispiel der realen Welt) ist es nicht so offensichtlich :) –

+0

@MicheleMariotti: "Verkettete Auswertung", wie Sie es sagen, ist nicht neu oder einzigartig für den ternären Operator. Ob eine teure Auswertung in einem Block wiederholt oder in einem ternären Operator eingeplant wird, das Ergebnis wäre das gleiche. Der Leistungsunterschied zwischen einer "logisch äquivalenten" In-Line oder einer Block-If-Then-Else wird immer noch verschwindend klein sein. Die typischerweise verwendete Optimierung in Blöcken, wo das Ergebnis einer teuren Optimierung wiederholt verwendet wird, ist das Zwischenspeichern des Ergebnisses, wie von Sean Patrick Floyd veranschaulicht. – scottb