Tôi không biết tại sao điều này phải khó hiểu như vậy. Điều này có thể được giải thích với 2 lý do, IMO.
- Biểu thức Lambda là biểu thức poly .
Tôi sẽ cho bạn biết điều này có nghĩa là gì và những JLS
từ xung quanh nó là gì. Nhưng về bản chất thì đây cũng giống như thuốc generic:
static class Me<T> {
T t...
}
loại T
ở đây là gì? Vâng, nó phụ thuộc. Nếu bạn làm :
Me<Integer> me = new Me<>(); // it's Integer
Me<String> m2 = new Me<>(); // it's String
biểu thức poly được nói rằng chúng phụ thuộc vào bối cảnh nơi chúng được sử dụng. Biểu thức Lambda là như nhau. Chúng ta hãy biểu hiện lambda trong sự cô lập ở đây:
(String str) -> str.length() <= 5
Khi bạn nhìn vào nó, đây là gì? Vâng, đó là một Predicate<String>
? Nhưng có thể là A Function<String, Boolean>
? Hoặc có thể là chẵn MyTransformer<String, Boolean>
, trong đó:
interface MyTransformer<String, Boolean> {
Boolean transform(String in){
// do something here with "in"
}
}
Các lựa chọn là vô tận.
- Trong lý thuyết
.negate()
gọi trực tiếp có thể là một lựa chọn.
Từ 10_000 dặm trên, bạn là chính xác: bạn đang cung cấp mà str -> str.length() <= 5
đến một removeIf
phương pháp, mà chỉ chấp nhận một Predicate
. Không còn removeIf
phương thức nào nữa , vì vậy trình biên dịch sẽ có thể "thực hiện đúng" khi bạn cung cấp phương thức đó (str -> str.length() <= 5).negate()
.
Vì vậy, làm thế nào điều này không hoạt động? Hãy bắt đầu với nhận xét của bạn:
Không phải lời kêu gọi phủ định () đã cung cấp nhiều ngữ cảnh hơn nữa, khiến cho việc phân vai rõ ràng thậm chí còn ít cần thiết hơn?
Có vẻ như đây là vấn đề chính bắt đầu, đây đơn giản không phải là cách javac
hoạt động. Nó không thể lấy toàn bộ str -> str.length() <= 5).negate()
, tự nói với mình rằng đây là một Predicate<String>
(vì bạn đang sử dụng nó làm đối số removeIf
) và sau đó phân tách thêm phần mà không có .negate()
và xem đó có phải là một Predicate<String>
. javac
hành động ngược lại, nó cần phải biết mục tiêu để có thể biết liệu nó có hợp pháp để gọi negate
hay không.
Ngoài ra, bạn cần phải phân biệt rõ ràng giữa các biểu thức poly và biểu thức , nói chung. str -> str.length() <= 5).negate()
là một biểu thức, str -> str.length() <= 5
là một biểu thức poly.
Có thể có những ngôn ngữ mà mọi thứ được thực hiện khác đi và nơi có thể, javac
đơn giản là không phải là loại ngôn ngữ đó .
Predicate<String> predicate = str -> str.length() <= 5; names.removeIf(predicate.negate()); names.removeIf(predicate);