No sé por qué esto tiene que ser tan confuso. Esto se puede explicar con 2 razones, la OMI.
- Las expresiones lambda son expresiones poli .
Dejaré que descubras qué significa esto y cuáles son las JLS
palabras que lo rodean. Pero en esencia, estos son como genéricos:
static class Me<T> {
T t...
}
¿Cuál es el tipo T
aquí? Bueno, eso depende. Si lo haces :
Me<Integer> me = new Me<>(); // it's Integer
Me<String> m2 = new Me<>(); // it's String
Se dice que las expresiones poli dependen del contexto de donde se usan. Las expresiones lambda son iguales. Tomemos la expresión lambda de forma aislada aquí:
(String str) -> str.length() <= 5
cuando lo miras, ¿qué es esto? Bueno es un Predicate<String>
? Pero puede ser A Function<String, Boolean>
? O puede ser incluso MyTransformer<String, Boolean>
, donde:
interface MyTransformer<String, Boolean> {
Boolean transform(String in){
// do something here with "in"
}
}
Las opciones son infinitas.
- En teoría,
.negate()
llamar directamente podría ser una opción.
Desde 10_000 millas arriba, está en lo correcto: está proporcionando eso str -> str.length() <= 5
a un removeIf
método, que solo acepta a Predicate
. No hay más removeIf
métodos, por lo que el compilador debería ser capaz de "hacer lo correcto" cuando lo proporcione (str -> str.length() <= 5).negate()
.
Entonces, ¿cómo es que esto no funciona? Comencemos con tu comentario:
¿No debería la llamada a negate () haber proporcionado aún más contexto, haciendo que el reparto explícito sea aún menos necesario?
Parece que aquí es donde comienza el problema principal, simplemente no es así como javac
funciona. No puede tomar todo str -> str.length() <= 5).negate()
, decirse a sí mismo que esto es un Predicate<String>
(ya que lo está utilizando como argumento para removeIf
) y luego descomponer aún más la parte sin .negate()
y ver si eso Predicate<String>
también es un . javac
actúa a la inversa, necesita conocer el objetivo para poder saber si es legal llamar negate
o no.
También debe hacer una distinción clara entre expresiones poli y expresiones , en general. str -> str.length() <= 5).negate()
es una expresión, str -> str.length() <= 5
es una expresión poli.
Puede haber idiomas donde las cosas se hacen de manera diferente y donde esto es posible, javac
simplemente no es ese tipo.
Predicate<String> predicate = str -> str.length() <= 5; names.removeIf(predicate.negate()); names.removeIf(predicate);