Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

212
Views
¿Por qué mapMulti necesita información de tipo en comparación con flatMap?

Quiero usar mapMulti en lugar de flatMap y refactoricé el siguiente código:

 // using flatMap (version 1) => returns Set<Item> var items = users.stream() .flatMap(u -> u.getItems().stream()) .collect(Collectors.toSet());

en esto (versión 2):

 // using mapMulti (version 2) => returns Set<Item> var items = users.stream() .<Item>mapMulti((u, consumer) -> u.getItems().forEach(consumer)) .collect(Collectors.toSet());

Ambos devuelven los mismos elementos. Sin embargo, tengo dudas sobre si realmente debería reemplazar todo mi flatMap con ese código más detallado de mapMulti . ¿Por qué necesito agregar la información de tipo antes de mapMuli ( .<Item>mapMulti ). Si no incluyo la información del tipo, devolverá un Set<Object> . (¿Cómo) puedo simplificar mapMulti ?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Tenga en cuenta que el tipo de inferencia de tipos requerido para deducir el tipo de flujo resultante cuando usa flatMap es muy diferente de cuando usa mapMulti .

Cuando usa flatMap , el tipo de flujo resultante es el mismo que el tipo de retorno del cuerpo lambda. Eso es algo especial de lo que el compilador ha sido diseñado para inferir variables de tipo (es decir, el compilador "lo sabe").

Sin embargo, en el caso de mapMulti , el tipo de flujo resultante que presumiblemente desea solo se puede inferir de las cosas que hace con el parámetro lambda del consumer . Hipotéticamente, el compilador podría diseñarse de modo que, por ejemplo, si ha dicho consumer.accept(1) , entonces miraría lo que ha pasado para accept , y vería que desea un Stream<Integer> , y en el En el caso de getItems().forEach(consumer) , el único lugar de donde podría haber venido el tipo Item es el tipo de devolución de getItems , por lo que tendría que buscarlo en su lugar.

Básicamente, le está pidiendo al compilador que infiera los tipos de parámetros de una lambda, en función de los tipos de expresiones arbitrarias que contiene. El compilador simplemente no ha sido diseñado para hacer esto.

Además de agregar el prefijo <Item> , hay otras formas (más largas) de permitirle inferir un Stream<Item> como el tipo de retorno de mapMulti :

Haz que la lambda se escriba explícitamente:

 var items = users.stream() .mapMulti((User u, Consumer<Item> consumer) -> u.getItems().forEach(consumer)) .collect(Collectors.toSet());

Agregue una variable de flujo temporal:

 // By looking at the type of itemStream, the compiler can figure out that mapMulti should return a Stream<Item> Stream<Item> itemStream = users.stream() .mapMulti((u, consumer) -> u.getItems().forEach(consumer)); var items = itemStream.collect(Collectors.toSet());

No sé si esto es más "simplificado", pero creo que es más ordenado si usa referencias de métodos:

 var items = users.stream() .map(User::getItems) .<Item>mapMulti(Iterable::forEach) .collect(Collectors.toSet());
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!