Gibt es einen eleganten Weg, um die erste nicht-null-Wert der multiplen-Methode gibt in Java?

Haben Sie schon gesehen, das viele Male selbst, ich bin mir sicher:

public SomeObject findSomeObject(Arguments args) {
    SomeObject so = queryFirstSource(args); //the most likely source first, hopefully
    if (so != null) return so;

    so = querySecondSource(args); //a source less likely than the first, hopefully
    if (so != null) return so;

    so = queryThirdSource(args); //a source less likely than the previous, hopefully
    if (so != null) return so;

    //and so on
}

Wir haben verschiedene Quellen, wo ein Objekt, das wir suchen, könnte sein. Wie ein lebendiger Beispiel könnten wir ein image, dass wir zuerst prüfen, ob eine Benutzer-id in einer Liste der privilegierten Benutzer. Wenn nicht, überprüfen wir, ob die Benutzer-id ist in der Liste der zulässigen Benutzer. Sonst haben wir null zurück. (Es ist nicht das beste Beispiel, aber ich hoffe, es ist ein lebendiger genug.)

Guave bietet uns einige Helfer, die könnte zu verschönern, die obigen code:

public SomeObject findSomeObject(Arguments args) {
    //if there are only two objects
    return com.google.common.base.Objects.firstNonNull(queryFirstSource(args), querySecondSource(args));

    //or else
    return com.google.common.collect.Iterables.find(
        Arrays.asList(
            queryFirstSource(args)
            , querySecondSource(args)
            , queryThirdSource(args)
            //, ...
        )
        , com.google.common.base.Predicates.notNull()
    );
 }

Aber, wie die erfahreneren unter uns werden schon gesehen haben, kann dies durchführen schlimm, wenn Sie die lookups (d.h. queryXXXXSource(args)) eine bestimmte Menge Zeit. Das ist, weil wir jetzt die Abfrage alle Quellen zuerst und dann übergeben Sie die Ergebnisse der Methode, findet die ersten unter den Ergebnissen, die nicht null.

Im Gegensatz zu dem ersten Beispiel, wo die nächste Quelle ist nur dann ausgewertet, wenn die ehemaligen nicht wieder etwas, diese zweite Lösung kann besser Aussehen, aber auf den ersten könnte durchführen viel schlimmer.

Hier kommen wir zu meiner eigentlichen Frage und zu denen ich schlage vor, etwas, dass ich hoffe, jemand hat bereits die Basis des es oder der, dass jemand vorschlagen könnte, eine noch ziepte Lösung.

Im Klartext: Hat schon jemand solches defferedFirstNonNull (siehe unten) oder etwas ähnliches? Gibt es eine einfache plain-Java-Lösung zu erreichen, diese mit den neuen Stream Rahmen? Können Sie schlagen eine andere elegante Lösung, erreicht das gleiche Ergebnis?

Regeln: Java 8 erlaubt ist sowie aktiv gepflegt und gut bekannt Bibliotheken von Drittanbietern wie Google Guava oder Apache Commons Lang Apache-Lizenz oder ähnliches (Nicht GPL!).

Die vorgeschlagene Lösung:

public SomeObject findSomeObject(Arguments args) {
    return Helper.deferredFirstNonNull(
        Arrays.asList(
            args -> queryFirstSource(args)
            , args -> querySourceSource(args)
            , args -> queryThirdSource(args)
        )
        , x -> x != null
     )
 }

Also die Methode defferedFirstNonNull bewerten würde jeder lambda-Ausdruck nach dem anderen und sobald das Prädikat (x -> x != null) wahr ist (D. H. haben wir eine übereinstimmung gefunden) die Methode liefert das Ergebnis sofort und würde nicht Abfragen weitere Quelle.

PS: ich weiß, dass die Ausdrücke args -> queryXXXXSource(args) gekürzt werden kann, um queryXXXXSource. Aber machen würde die vorgeschlagene Lösung schwieriger zu Lesen, da es nicht offensichtlich auf den ersten Blick, was geschehen wird.

InformationsquelleAutor cimnine | 2014-09-30
Schreibe einen Kommentar