Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

120
Vistas
filtrar una secuencia cambia sus límites comodín?

el siguiente método se compila sin problemas:

 static Stream<Optional<? extends Number>> getNumbers(Stream<Number> numbers) { return numbers.map(Optional::of); }

sin embargo, si le agrego un filtrado simple como este:

 static Stream<Optional<? extends Number>> getNumbers2(Stream<Number> numbers) { return numbers.map(Optional::of).filter(number -> true); }

genera el siguiente error:

tipos incompatibles:
java.util.stream.Stream<java.util.Optional<java.lang.Number>> no se puede convertir a
java.util.stream.Stream<java.util.Opcional<? extiende java.lang.Number>>

probado en openJdk-11 y openJdk-17.

Esperaría que ambos hicieran lo mismo (o ambos compilan bien o ambos generan el mismo error de compilación), así que estoy realmente desconcertado por esto: ¿cuál es la regla general aquí que explica por qué el primer método compila bien pero el segundo ¿no? ¡Gracias!

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Compatibilidad con el tipo de retorno Stream<Optional<? extends Number>> en el primer caso no se obtiene en virtud de numbers.map(Optional::of) que devuelve un Stream<Optional<? extends Number>> por sí mismo; es el compilador el que infiere el tipo de retorno de numbers.map(...) debido a que es un método genérico:

 <R> Stream<R> map(Function<? super T, ? extends R> mapper);

mientras que Stream.filter() no lo es:

 Stream<T> filter(Predicate<? super T> predicate);

Por lo tanto, en el primer caso, el compilador puede tener en cuenta el contexto de la instrucción de retorno (tipo de getNumbers ) al inferir el tipo de numbers.map(...) .
El compilador no puede hacer lo mismo para los numbers.map(...) en el segundo caso, ya que hay llamadas encadenadas posteriores, que pueden cambiar aún más el tipo, por lo que sería muy difícil adivinar cuál debería ser la inferencia correcta en esta etapa. . Como resultado, se asume el tipo posible más específico para numbers.map(...) ( Stream<Optional<Number>> ) y se continúa con filter(...) .

Como un ejemplo diferente para ilustrar eso, descubra por qué ambos compilan ( List.of() es el mismo código, después de todo):

 static List<String> stringList() { return List.of(); } static List<Integer> intList() { return List.of(); }

Ahora, ¿por qué falla esto?

 static List<String> stringList() { return List.of().subList(0, 0); }

Esto se debe a que List.subList(...) no infiere el tipo E de la lista devuelta en contexto (es decir, el método no es genérico), lleva el tipo E de la instancia de List , que, con List.of() en ese caso obtiene el valor predeterminado es Object (sí, cuando tiene return List.of(); , se activa la inferencia de tipo de retorno, lo que obliga al compilador a darse cuenta de que la intención es hacer que E coincida con String , el argumento de tipo en el tipo de retorno del método). Tenga en cuenta que esto se vuelve más complejo que eso, hay esquinas donde la inferencia no funciona como se desea/espera.


Respuesta corta : return numbers.map(Optional::of) aprovecha la inferencia de tipo ya que map() es genérico y filter() no, esperando que se transporte la E de Stream<E> . Y con numbers.map(Optional::of) , E es Optional<Number> , no Optional<? extends Number> , y el filter lo lleva.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda