Vị từ Java 8 tích hợp luôn trả về giá trị true?


129

Google Guava có một vị ngữ luôn luôn trả vềtrue . Java 8 có cái gì đó tương tự Predicatekhô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:


161

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

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 -> truelầ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() -> { }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 -> xlà 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.orvà 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 .


14
Hai mối quan tâm: Thứ nhất là ngắn gọn. Nếu (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ên x->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ụng x->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ới Predicate.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->truelà gần như tốt, nhưng tôi vẫn viết một Predicate.alwaysTrue()phương pháp cho các lý do trên.
Garret Wilson

10
@GarretWilson Nhưng với Predicate.alwaysTrue()bạn cũng có thể làm hỏng bằng cách vô tình viết Predicate.alwaysFalse().
David Conrad

5
@DavidConrad, tất nhiên. Luôn có những cách tôi có thể phạm sai lầm, và trên thực tế tôi liên tục phát minh ra những cái mới. ;) Tôi không muốn bắt đầu một cuộc tranh luận ở đây về một điều gì đó tầm thường, nhưng tôi sẽ chỉ nói rằng quan điểm của tôi là với một tham chiếu phương thức tĩnh, tôi có một từ vựng bị hạn chế chỉ với hai lựa chọn: alwaysTrue()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->truethự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.
Garret Wilson

25
Một lợi thế lớn của kinh điển Predicate.alwaysTrue()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 Predicatebiến với alwaysTrue()và thêm các biến vị ngữ bằng cách kết hợp thông qua andmà 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 Xvới một staticphương thức y(){return true;}, thì việc sử dụng X::ythậm chí còn ngắn hơn x->truenhưng không thực sự được khuyến nghị nên
Holger

10
Thành ngữ x -> truecó 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 ^^)
kap

4

Không có ổi

Boolean.TRUE::booleanValue

3
Nó thật thú vị. Tôi không chắc liệu nó có hoàn toàn nắm bắt được tinh thần của yêu cầu hay không, nhưng nó nhận được điểm cho sự sáng tạo!
Garret Wilson

21
Nhưng nó không phải là một Predicate, vì nó không tranh luận.
Florent Guillaume

1
Nó không phải là một vị ngữ, nó là một tham chiếu phương thức nhưng nó có giá trị ngắn gọn và không buộc phải đề cập đến một tham số không sử dụng. +1 Nhân tiện, vì nó tránh sử dụng Guava có vấn đề nghiêm trọng về tính mô đun, nó xứng đáng với sự
ủng hộ

16
Tham chiếu phương thức của bạn được gán cho Nhà cung cấp <Boolean> nhưng không phải là Vị ngữ <T>
Daniel K.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.