it-swarm.com.de

Überprüfen Sie, ob der zurückgegebene Wert nicht null ist, und weisen Sie ihn in einer Zeile mit einem Methodenaufruf zu

Java ist mit folgenden Anweisungen übersät:

if(cage.getChicken() != null) {
    dinner = cage.getChicken();
} else {
    dinner = getFreeRangeChicken();
}

Dies erfordert zwei Aufrufe an getChicken(), bevor das zurückgegebene Objekt dinner zugewiesen werden kann.

Dies könnte auch so in eine Zeile geschrieben werden:

dinner = cage.getChicken() != null? cage.getChicken() : getFreeRangeChicken();

Aber leider gibt es noch zwei Aufrufe von getChicken().

Natürlich könnten wir eine lokale Variable zuweisen und dann den ternären Operator erneut verwenden, um sie zuzuweisen, wenn sie nicht null ist. Dies ist jedoch zwei Zeilen und nicht so hübsch:

FutureMeal chicken = cage.getChicken();
dinner = chicken != null? chicken : getFreeRangeChicken();

Gibt es eine Möglichkeit zu sagen:

Variable var = irgendein Wert, wenn ein Wert nicht null ist OR ein anderer Wert;

Und ich denke, ich spreche hier nur über Syntax. Nachdem der Code kompiliert wurde, macht es wahrscheinlich keinen großen Unterschied, wie der Code aus Performance-Gründen geschrieben wurde.

Da dies ein allgemeiner Code ist, wäre es großartig, einen Einzeiler zum Schreiben zu haben.

Haben andere Sprachen diese Funktion?

32
Continuity8

Java fehlt der Coalesce-Operator. Daher ist Ihr Code mit einem expliziten temporären Code die beste Wahl für eine Zuweisung mit einem einzigen Aufruf.

Sie können die Ergebnisvariable als temporär verwenden:

dinner = ((dinner = cage.getChicken()) != null) ? dinner : getFreeRangeChicken();

Dies ist jedoch schwer zu lesen.

40
dasblinkenlight

Gleiches Prinzip wie Lokis Antwort, aber kürzer. Denken Sie daran, dass kürzer nicht automatisch besser ist.

dinner = Optional.ofNullable(cage.getChicken())
  .orElse(getFreerangeChicken());

Hinweis: Diese Verwendung von Optional wird ausdrücklich von den Architekten des JDK und den Designern der optionalen Funktion empfohlen. Sie ordnen ein neues Objekt zu und werfen es jedes Mal sofort weg. Andererseits kann es durchaus lesbar sein.

44
jhyot

Mit Java 1.8 können Sie Optional verwenden.

public class Main  {

    public static void main(String[] args) {

        //example call, the methods are just dumb templates, note they are static
        FutureMeal meal = getChicken().orElse(getFreeRangeChicken());

        //another possible way to call this having static methods is
        FutureMeal meal = getChicken().orElseGet(Main::getFreeRangeChicken); //method reference

        //or if you would use a Instance of Main and call getChicken and getFreeRangeChicken
        // as nonstatic methods (assume static would be replaced with public for this)
        Main m = new Main();
        FutureMeal meal = m.getChicken().orElseGet(m::getFreeRangeChicken); //method reference

        //or
        FutureMeal meal = m.getChicken().orElse(m.getFreeRangeChicken()); //method call


    }

    static Optional<FutureMeal> getChicken(){

        //instead of returning null, you would return Optional.empty() 
        //here I just return it to demonstrate
        return Optional.empty();

        //if you would return a valid object the following comment would be the code
        //FutureMeal ret = new FutureMeal(); //your return object
        //return Optional.of(ret);            

    }

    static FutureMeal getFreeRangeChicken(){
        return new FutureMeal();
    }
}

Sie würden eine Logik für getChicken implementieren, um entweder Optional.empty() anstelle von null oder Optional.of(myReturnObject) zurückzugeben, wobei myReturnObject Ihre chicken ist.

Dann können Sie getChicken() aufrufen und wenn Optional.empty() zurückgegeben würde, würde die orElse(fallback) Ihnen den Fallback geben, der in Ihrem Fall die zweite Methode wäre.

11
Loki

Wenn Sie noch nicht mit Java 1.8 arbeiten und es Ihnen nichts ausmacht, commons-lang zu verwenden, können Sie org.Apache.commons.lang3.ObjectUtils # defaultIfNull verwenden.

Ihr Code wäre:

dinner = ObjectUtils.defaultIfNull(cage.getChicken(),getFreeRangeChicken())
10
Pieter De Bie

Verwenden Sie Ihre eigenen

public static <T> T defaultWhenNull(@Nullable T object, @NonNull T def) {
    return (object == null) ? def : object;
}

Beispiel:

defaultWhenNull(getNullableString(), "");

Vorteile

  • Funktioniert, wenn Sie nicht in Java8 entwickeln  
  • Funktioniert für die Android-Entwicklung mit Unterstützung für vor API 24 -Geräte
  • Benötigt keine externe Bibliothek

Nachteile

  • Wertet immer den default value aus (wie von cond ? nonNull() : notEvaluated() vorgeschlagen)

    Dies könnte umgangen werden, indem ein Callable anstelle eines Standardwerts übergeben wird, jedoch etwas komplizierter und weniger dynamisch wird (z. B. wenn die Leistung ein Problem ist).

    Übrigens stößt man bei der Verwendung von Optional.orElse() auf den gleichen Nachteil ;-)

1
Levit
dinner = cage.getChicken();
if(dinner == null) dinner = getFreeRangeChicken();

oder

if( (dinner = cage.getChicken() ) == null) dinner = getFreeRangeChicken();
1
crashxxl

Seit Java 9 haben Sie Objects # requirNonNullElse was Folgendes macht:

public static <T> T requireNonNullElse(T obj, T defaultObj) {
    return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}

Ihr Code wäre

dinner = Objects.requireNonNullElse(cage.getChicken(), getFreeRangeChicken());

Welches ist 1 Zeile und ruft getChicken() nur einmal auf, so dass beide Anforderungen erfüllt sind.

Beachten Sie, dass das zweite Argument nicht auch null sein kann. Diese Methode erzwingt eine Nichtnullheit des zurückgegebenen Werts.

Beachten Sie auch die alternativen Objekte # requirNonNullElseGet :

public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)

das zweite Argument wird nicht einmal ausgewertet, wenn das erste nicht null ist, sondern den Aufwand für das Erstellen einer Supplier hat.

0
user1803551

Alternativ können Sie in Java8 die Annotationen Nullable oder NotNull entsprechend Ihren Bedürfnissen verwenden.

 public class TestingNullable {
        @Nullable
        public Color nullableMethod(){
            //some code here
            return color;
        }

        public void usingNullableMethod(){
            // some code
            Color color = nullableMethod();
            // Introducing assurance of not-null resolves the problem
            if (color != null) {
                color.toString();
            }
        }
    }

 public class TestingNullable {
        public void foo(@NotNull Object param){
            //some code here
        }

        ...

        public void callingNotNullMethod() {
            //some code here
            // the parameter value according to the explicit contract
            // cannot be null
            foo(null);
        }
    }

http://mindprod.com/jgloss/atnullable.html

0
shan