Google Guava có một vị ngữ luôn luôn trả vềtrue
. Java 8 có cái gì đó tương tự Predicate
không? Tôi biết tôi có thể sử dụng (foo)->{return true;}
, nhưng tôi muốn một cái gì đó được làm sẵn, tương tự Collections.emptySet()
.
Google Guava có một vị ngữ luôn luôn trả vềtrue
. Java 8 có cái gì đó tương tự Predicate
không? Tôi biết tôi có thể sử dụng (foo)->{return true;}
, nhưng tôi muốn một cái gì đó được làm sẵn, tương tự Collections.emptySet()
.
Câu trả lời:
Không có các biến vị ngữ luôn luôn đúng và luôn luôn sai trong Java 8. Cách viết ngắn gọn nhất này là
x -> true
và
x -> false
So sánh những điều này với
Predicates.alwaysTrue() // Guava
và cuối cùng đến một lớp bên trong vô danh:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
Có lẽ lý do mà Guava có các vị từ tích hợp này là vì có một lợi thế cú pháp rất lớn của một cuộc gọi phương thức tĩnh đối với một lớp bên trong ẩn danh. Trong Java 8, cú pháp lambda ngắn gọn đến nỗi có một nhược điểm cú pháp khi viết ra một cuộc gọi phương thức tĩnh.
Đó chỉ là một so sánh cú pháp. Có lẽ có một lợi thế không gian nhỏ nếu có một vị từ luôn luôn đúng toàn cầu, so với các x -> true
lần xuất hiện trải rộng trên nhiều lớp, mỗi lớp sẽ tạo ra một thể hiện vị ngữ riêng. Đây có phải là những gì bạn quan tâm? Các khoản tiết kiệm dường như không hấp dẫn, đó có thể là lý do tại sao chúng không được thêm vào ngay từ đầu. Nhưng nó có thể được xem xét lại cho một bản phát hành trong tương lai.
CẬP NHẬT 2015-04-24
Chúng tôi đã xem xét việc bổ sung một loạt các hàm tĩnh, được đặt tên như Predicate.alwaysTrue
,Runnable.noop
, vv, và chúng tôi đã quyết định không thêm nữa trong các phiên bản tương lai của Java SE.
Chắc chắn có một số giá trị trong một cái gì đó có tên so với lambda viết ra, nhưng giá trị này là khá nhỏ. Chúng tôi hy vọng rằng mọi người sẽ học cách đọc và viết x -> true
và () -> { }
việc sử dụng của họ sẽ trở nên thành ngữ. Ngay cả giá trị của Function.identity()
hơn x -> x
là nghi vấn.
Có một lợi thế hiệu suất nhỏ để sử dụng lại một chức năng hiện có thay vì đánh giá lambda đã viết ra, nhưng chúng tôi hy vọng việc sử dụng các loại chức năng này quá nhỏ đến mức lợi thế đó không đáng kể, chắc chắn không đáng để làm hỏng API.
Holger cũng đề cập trong các ý kiến về khả năng tối ưu hóa các chức năng tổng hợp như Predicate.or
và như vậy. Điều này cũng đã được xem xét ( JDK-8067971 ) nhưng được coi là hơi mong manh và dễ bị lỗi, và xảy ra không thường xuyên đến mức nó không đáng để nỗ lực thực hiện.
Xem thêm mục Câu hỏi thường gặp Lambda này .
Predicate.alwaysTrue()
bạn cũng có thể làm hỏng bằng cách vô tình viết Predicate.alwaysFalse()
.
alwaysTrue()
và alwaysFalse()
. Với lambda thực tế, tôi có nhiều biến thể; Tôi về cơ bản là xây dựng lại công thức mỗi lần. Về bản chất, alwaysTrue()
là một nhãn ngữ nghĩa cho những gì tôi muốn làm; x->true
thực sự đang làm lại từ đầu mỗi lần Không lớn, nhưng một sự cân nhắc.
Predicate.alwaysTrue()
và Predicate.alwaysFalse()
các trường hợp là, rằng họ có thể được công nhận bằng cách kết hợp các phương pháp như Predicate.or
, Predicate.and
, và Predicate.negate()
. Điều này sẽ cho phép khởi tạo trước các Predicate
biến với alwaysTrue()
và thêm các biến vị ngữ bằng cách kết hợp thông qua and
mà không cần phí. Vì các biểu thức lambda không có bảo đảm nhận dạng đối tượng, điều này có thể thất bại với x->true
. Nhân tiện, nếu tôi có một lớp X
với một static
phương thức y(){return true;}
, thì việc sử dụng X::y
thậm chí còn ngắn hơn x->true
nhưng không thực sự được khuyến nghị nên
x -> true
có nhược điểm là tôi phải sử dụng một biến mà không sử dụng. Điều này tạo ra tải não không cần thiết và cũng là một cảnh báo trong IDE của tôi. Tôi đã cố gắng sử dụng _ -> true
, nhưng đó là một lỗi cú pháp. Java chắc chắn thiếu một từ khóa (đọc: keyletter) cho "tham số không sử dụng". Hy vọng rằng một cái gì đó như thế này sẽ xuất hiện trong Java 9 (hoặc ít nhất là: Java bất cứ điều gì trước khi tôi chết ^^)
Không có ổi
Boolean.TRUE::booleanValue
Predicate
, vì nó không tranh luận.
(foo)->{return true;}
là điều tốt nhất tôi có thể làm, tôi muốn tốt hơn. Nhưng bạn đã đưa lênx->true
, đó là tốt hơn nhiều và giảm nhẹ vấn đề đầu tiên. Vấn đề thứ hai là logic và khai báo tĩnh. Nếu tôi sử dụngx->true
, vẫn còn logic liên quan, mà tôi có thể vô tình làm hỏng (ví dụx->!true
). Nhưng vớiPredicate.alwaysTrue()
, không có chỗ cho lỗi logic, vì chỉ có một hoặc hai phương thức tương tự. Thêm vào đó tôi nhận được hoàn thành mã IDE miễn phí.x->true
là gần như tốt, nhưng tôi vẫn viết mộtPredicate.alwaysTrue()
phương pháp cho các lý do trên.