2014-11-14 9 views
21

Sto lavorando con Twitter4J. Ma la domanda che sto facendo è più generale. Voglio accedere all'ID utente di un dato tweet. Attualmente, ho le seguenti due opzioni:Riferimenti al metodo Chain of Map

//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); 

non mi piace l'espressione lambda nella prima opzione, e non essere costretti a chiamare due maps nel secondo. C'è un modo per fare una catena di riferimenti al metodo? So che Status::getUser::getId non funziona, ma mi chiedo se c'è un'alternativa.

+1

Perché non ti piacciono 2 chiamate 'map'? Ti preoccupi per le prestazioni? Non è necessario: lo stream verrà elaborato in un unico passaggio. –

+5

Verbosità. Per la stessa ragione 'status.getUser(). GetId()' esiste, speravo che qualcosa come 'Status :: getUser :: getId' esista. – mossaab

risposta

14

No, questi sono i due modi per farlo. Qualcos'altro finirebbe per essere solo meno chiaro.

Ma, dal momento che hai chiesto, ecco alcune opzioni.

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)) 

O

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

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

In realtà, entrambi gli approcci fanno ciò che chiama 'map' due volte, con la differenza che lo stream userà sempre' Function.andThen' o 'Function.compose 'invece di ri-implementare esso stesso (come il metodo' chain') . – Holger

+1

Stavo cercando qualcosa che eviti di chiamare la classe 'User', perché dovrebbe essere dedotta direttamente da' getUser'. Accetto "Nope" come risposta. – mossaab

1

Delle due opzioni proposte, tendo a usare la seconda, il concatenamento chiamate a map().

ci sono altre opzioni, che utilizza built-in API, invece di metodi di supporto, come mostrato here. Con le Function.compose() o Function.andThen() metodi, è possibile invocazioni funzione della catena. Predicate e altre interfacce funzionali implementano metodi predefiniti simili.

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

alternativa

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

Lo svantaggio è che, al fine di utilizzare questi, il tipo di interfaccia funzionale deve essere data esplicitamente. Ciò richiede un cast o un incarico e sembra un po 'brutto. Quindi, per una catena di mappatura, di solito uso più chiamate map().

Problemi correlati