2014-11-14 9 views
21

Ich bin mit Twitter4J arbeiten. Aber die Frage, die ich stelle, ist allgemeiner. Ich möchte auf die Benutzer-ID eines bestimmten Tweets zugreifen. Derzeit habe ich die folgenden zwei Möglichkeiten:Chain of Map-Methode verweist

//Option 1 
stream.map(status -> status.getUser().getId()) 
     .forEach(System.out::println); 

//Option 2: 
stream.map(Status::getUser) 
     .map(User:getId) 
     .forEach(System.out::println); 

Ich mag nicht den Lambda-Ausdruck in der ersten Option, noch gezwungen, zwei maps in dem zweiten Frage zu nennen. Gibt es eine Möglichkeit, eine Kette von Methodenreferenzen zu erstellen? Ich weiß, dass Status::getUser::getId nicht funktioniert, aber ich frage mich, ob es eine Alternative gibt.

+1

Warum Sie nicht wie 2 'map' Anrufe? Machst du dir Sorgen über die Leistung? Sie müssen nicht - der Stream wird in einem Durchgang verarbeitet. –

+5

Ausführlichkeit. Aus dem gleichen Grund 'status.getUser(). GetId()' existiert, hoffte ich, dass so etwas wie 'Der Status :: getUser :: getId' existiert. – mossaab

Antwort

14

Nein, das sind die zwei Möglichkeiten, es zu tun. Alles andere würde nur weniger klar sein.

Aber, da Sie hier gefragt sind einige Optionen.

static<T,U,R> Function<T,R> chain(
     Function<? super T, ? extends U> f1, 
     Function<? super U, ? extends R> f2) { 
    return t -> f2.apply(f1.apply(t)); 
} 

stream.map(chain(Status::getUser, User::getId)) 

Oder

static<T,R> Function<T,R> func(Function<T,R> f) { 
    return f; 
} 

stream.map(func(Status::getUser).andThen(User::getId)) 
+2

Eigentlich machen beide Ansätze, was "map" zweimal aufruft, der einzige Unterschied ist, dass der Stream immer 'Function.andThen' oder' Function.compose' verwendet anstatt ihn selbst zu re-implementieren (wie Ihre 'chain' Methode) . – Holger

+1

Ich war auf der Suche nach etwas, das die Klasse 'User' vermeidet anrufen, weil sie direkt von' getUser' rein zufällig. Ich akzeptiere "Nein" als Antwort. – mossaab

1

Von den beiden vorgeschlagenen Optionen, neige ich dazu, das zweite Gerät, Anrufe zu map() verketten.

Es gibt andere Optionen, die integrierte API anstelle von Hilfsmethoden verwenden, wie gezeigt here. Mit den Methoden Function.compose() oder Function.andThen() können Sie Funktionsaufrufe verketten. Predicate und andere funktionale Schnittstellen implementieren ähnliche Standardmethoden.

stream.map(((Function<Status, User>) Status::getUser).andThen(User::getId)) 
    .forEach(System.out::println); 

Alternativ

Function<Status, User> toUser = Status::getUser; 
stream.map(toUser.andThen(User::getId)).forEach(System.out::println); 

Der Nachteil ist, dass es, um diesen, die funktionelle Schnittstellentyp explizit angegeben werden muss, zu verwenden. Das erfordert eine Besetzung oder eine Aufgabe, und das sieht ein bisschen hässlich aus. Für eine Zuordnungskette verwende ich normalerweise mehrere Anrufe map().

Verwandte Themen