Có một cách để soạn một tham chiếu phương thức ngược lại với tham chiếu phương thức hiện tại. Xem câu trả lời của @ vlasec dưới đây cho thấy cách bằng cách chuyển rõ ràng tham chiếu phương thức sang a Predicate
và sau đó chuyển đổi nó bằng negate
hàm. Đó là một cách trong số một vài cách khác không quá rắc rối để làm điều đó.
Trái ngược với điều này:
Stream<String> s = ...;
int emptyStrings = s.filter(String::isEmpty).count();
có phải đây là:
Stream<String> s = ...;
int notEmptyStrings = s.filter(((Predicate<String>) String::isEmpty).negate()).count()
hoặc này:
Stream<String> s = ...;
int notEmptyStrings = s.filter( it -> !it.isEmpty() ).count();
Cá nhân, tôi thích kỹ thuật sau này vì tôi thấy nó rõ ràng hơn để đọc it -> !it.isEmpty()
hơn một dàn diễn viên dài dòng rõ ràng và sau đó phủ nhận.
Người ta cũng có thể tạo một vị ngữ và sử dụng lại nó:
Predicate<String> notEmpty = (String it) -> !it.isEmpty();
Stream<String> s = ...;
int notEmptyStrings = s.filter(notEmpty).count();
Hoặc, nếu có một bộ sưu tập hoặc mảng, chỉ cần sử dụng một vòng lặp for đơn giản, có ít chi phí hơn và * có thể nhanh hơn **:
int notEmpty = 0;
for(String s : list) if(!s.isEmpty()) notEmpty++;
* Nếu bạn muốn biết cái gì nhanh hơn, thì hãy sử dụng JMH http://openjdk.java.net/projects/code-tools/jmh và tránh mã điểm chuẩn tay trừ khi nó tránh được tất cả các tối ưu hóa JVM - xem Java 8: hiệu suất của Luồng vs Bộ sưu tập
** Tôi nhận được thông báo rằng kỹ thuật for-loop nhanh hơn. Nó loại bỏ việc tạo luồng, nó loại bỏ bằng cách sử dụng một lệnh gọi phương thức khác (hàm phủ định cho vị ngữ) và loại bỏ một danh sách / bộ đếm tích lũy tạm thời. Vì vậy, một vài thứ được lưu bởi cấu trúc cuối cùng có thể làm cho nó nhanh hơn.
Tôi nghĩ rằng nó đơn giản và đẹp hơn mặc dù không nhanh hơn. Nếu công việc yêu cầu búa và đinh, đừng mang cưa và keo! Tôi biết một số bạn có vấn đề với điều đó.
wish-list: Tôi muốn thấy các Stream
hàm Java phát triển một chút khi người dùng Java đã quen thuộc hơn với chúng. Ví dụ: phương pháp 'đếm' trong Luồng có thể chấp nhận Predicate
để có thể thực hiện trực tiếp như thế này:
Stream<String> s = ...;
int notEmptyStrings = s.count(it -> !it.isEmpty());
or
List<String> list = ...;
int notEmptyStrings = lists.count(it -> !it.isEmpty());
Predicate.not(Predicate)
phương thức tĩnh . Nhưng vấn đề đó vẫn còn mở nên chúng ta sẽ thấy vấn đề này sớm nhất trong Java 12 (nếu có).