Não sei por que isso deve ser tão confuso. Isso pode ser explicado por 2 razões, IMO.
- Expressões lambda são expressões polis .
Vou deixar você descobrir o que isso significa e quais JLS
são as palavras ao seu redor. Mas, em essência, são como genéricos:
static class Me<T> {
T t...
}
qual é o tipo T
aqui? Bem, isto depende. Se você fizer :
Me<Integer> me = new Me<>(); // it's Integer
Me<String> m2 = new Me<>(); // it's String
Dizem-se que expressões poli dependem do contexto de onde são usadas. As expressões lambda são as mesmas. Vamos considerar a expressão lambda isoladamente aqui:
(String str) -> str.length() <= 5
quando você olha para isso, o que é isso? Bem, é um Predicate<String>
? Mas pode ser A Function<String, Boolean>
? Ou pode ser par MyTransformer<String, Boolean>
, onde:
interface MyTransformer<String, Boolean> {
Boolean transform(String in){
// do something here with "in"
}
}
As escolhas são infinitas.
- Em teoria,
.negate()
chamado diretamente poderia ser uma opção.
A partir das 10_000 milhas acima, você está correto: você está fornecendo isso str -> str.length() <= 5
a um removeIf
método, que aceita apenas a Predicate
. Não há mais removeIf
métodos, portanto, o compilador deve ser capaz de "fazer a coisa correta" quando você fornecer isso (str -> str.length() <= 5).negate()
.
Então, como é que isso não funciona? Vamos começar com o seu comentário:
A chamada para negate () não deveria fornecer ainda mais contexto, tornando a conversão explícita ainda menos necessária?
Parece que é aqui que o principal problema começa, simplesmente não é assim que javac
funciona. Não pode pegar o todo str -> str.length() <= 5).negate()
, diga a si mesmo que esse é um Predicate<String>
(já que você o está usando como argumento removeIf
) e depois decomponha ainda mais a parte sem .negate()
e veja se isso Predicate<String>
também é. javac
age de maneira inversa, precisa conhecer o alvo para saber se é legal ligar negate
ou não.
Além disso, você precisa fazer uma distinção clara entre expressões poli e expressões , em geral. str -> str.length() <= 5).negate()
é uma expressão, str -> str.length() <= 5
é uma expressão poli.
Pode haver idiomas em que as coisas são feitas de maneira diferente e onde isso é possível, javac
simplesmente não é desse tipo.
Predicate<String> predicate = str -> str.length() <= 5; names.removeIf(predicate.negate()); names.removeIf(predicate);