1. Kiểm tra
Tôi nghĩ bạn có thể đã chán với việc học cách xâu chuỗi các luồng dữ liệu lại với nhau. Bạn muốn cuối cùng làm điều gì đó với dữ liệu.
Lớp Stream
có ba phương thức tiêu chuẩn không xây dựng luồng mà thay vào đó kiểm tra loại dữ liệu nào có trong đó. Những phương pháp này là: anyMatch()
, allMatch()
, và noneMatch()
.
boolean anyMatch(rule)
phương pháp
Phương thức này kiểm tra xem luồng có ít nhất một phần tử thỏa mãn quy tắc được truyền cho phương thức hay không. Nếu có một phần tử như vậy, phương thức trả về true
, nếu không thì false
.
ví dụ
Mã số | Ghi chú |
---|---|
|
|
|
|
|
|
Trong ví dụ trước, trước tiên chúng tôi chỉ giữ lại các phần tử nhỏ hơn 0, sau đó chúng tôi kiểm tra kết quả để xem liệu có bất kỳ phần tử nào được lọc lớn hơn 0 hay không. Tất nhiên, những yếu tố như vậy không còn nữa.
phương thức boolean allMatch(quy tắc)
Phương thức này kiểm tra xem tất cả các phần tử trong luồng có khớp với quy tắc hay không (còn được gọi là vị từ). Quy tắc được truyền dưới dạng đối số cho phương thức:
Mã số | Ghi chú |
---|---|
|
(tất cả các phần tử lớn hơn 0) |
|
(có phần tử nào nhỏ hơn hoặc bằng 0 không?) |
|
(chúng tôi đã giữ lại các phần tử nhỏ hơn 0) |
Trong ví dụ trước, trước tiên chúng tôi chỉ cho phép các phần tử nhỏ hơn 0 đi qua bộ lọc, sau đó chúng tôi kiểm tra xem tất cả các phần tử được giữ lại có nhỏ hơn 0 hay không. Việc kiểm tra mang lại một kết quả tích cực.
phương thức boolean noneMatch(quy tắc)
Phương noneMatch()
thức kiểm tra xem luồng có phần tử nào khớp với quy tắc đã thông qua hay không. Nó giống như sự đối lập của anyMatch()
phương pháp.
Mã số | Ghi chú |
---|---|
|
|
|
|
|
|
2. Các lớp tiện ích: Optional
đẳng cấp
Đôi khi rất bất tiện cho người lập trình khi làm việc với null
các tham chiếu. Ví dụ: giả sử bạn đang so sánh hai chuỗi. Nếu cả hai biến đều không null
, thì bạn chỉ cần gọi s1.equals(s2)
và mọi thứ sẽ hoạt động. Nhưng nếu s1
có thể null
, thì bạn phải viết mã xử lý tình huống này để tránh lỗi NullPointerException
.
Đó là lý do tại sao các lập trình viên đã nghĩ ra Optional<T>
lớp tiện ích. Mã của nó trông đại khái như thế này:
Mã số | Ghi chú |
---|---|
|
Kiểm tra xem giá trị có phải không null Kiểm tra xem giá trị có null Trả về giá trị được lưu trữ hay không. Ném một ngoại lệ nếu giá trị là null. Trả về giá trị khác null được lưu trữ. Hoặc nếu giá trị được lưu trữ là null , sau đó trả về giá trị được truyền dưới dạng đối số phương thức Trả về giá trị khác null được lưu trữ hoặc đưa ra một ngoại lệ nếu giá trị là null. |
Mục đích của lớp này chỉ đơn giản là lưu trữ một đối tượng T (một tham chiếu đến một đối tượng có kiểu là T). Tham chiếu đối tượng bên trong một Optional<T>
đối tượng có thể là null
.
Lớp này cho phép các lập trình viên viết mã đẹp hơn một chút. Hãy so sánh:
Sử dụng tùy chọn | Không sử dụng Tùy chọn |
---|---|
|
|
Một Optional
đối tượng luôn có thể được so sánh với một Optional
đối tượng khác bằng equals
phương thức này, ngay cả khi chúng lưu trữ null
các tham chiếu.
Nói một cách đơn giản, Optional
lớp này cho phép bạn viết các kiểm tra "đẹp" null
và các hành động "đẹp" trong trường hợp một Optional
đối tượng lưu trữ một null
giá trị.
3. Tìm phần tử
Hãy trở lại Stream
lớp học. Lớp này Stream
có thêm 4 phương thức cho phép bạn tìm kiếm các phần tử trong luồng. Những phương pháp này là findFirst()
, findAny()
, min()
, và max()
.
Optional<T> findFirst()
phương pháp
Phương thức này findFirst()
chỉ trả về phần tử đầu tiên trong luồng. Đó là tất cả những gì nó làm.
Điều thú vị hơn cần lưu ý ở đây là phương thức này không trả về một T
đối tượng, mà là một Optional<T>
đối tượng bao bọc. Điều này đảm bảo rằng phương thức sẽ không bao giờ quay lại null
sau khi không tìm thấy đối tượng.
Ví dụ:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String str = list.stream().findFirst().get(); // Hello
Để làm rõ hơn, hãy chia dòng cuối cùng thành nhiều dòng:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Hello
Phương thức cuối cùng get()
chỉ đơn giản là truy xuất giá trị được lưu trữ bên trong Optional
đối tượng.
Optional<T> findAny()
phương pháp
Phương findAny()
thức trả về bất kỳ phần tử nào từ luồng và kết thúc ở đó. Phương pháp này tương tự như findFirst()
, nhưng nó rất tốt cho các luồng được sử dụng trong các hoạt động song song.
Khi xử lý các luồng song song, có thể một phần tử đã được tìm thấy trong một số phần của luồng, nhưng vẫn chưa rõ đó có phải là phần tử đầu tiên hay không.
Nếu nhiều phần tử khớp với tất cả các bộ lọc và điều quan trọng là lập trình viên phải lấy chính xác phần tử đầu tiên trong số chúng, thì phương findFirst()
thức nên được gọi. Nếu lập trình viên biết rằng trong thực tế, 0 hoặc 1 phần tử sẽ khớp với tất cả các bộ lọc, thì chỉ cần gọi là đủ findAny()
- và điều này sẽ nhanh hơn.
Optional<T> min(Comparator<T>)
phương pháp
Phương thức này min()
sử dụng một comparator
đối tượng để so sánh tất cả các phần tử trong luồng và trả về phần tử tối thiểu. Cách thuận tiện nhất để xác định đối tượng so sánh là sử dụng hàm lambda.
Ví dụ tìm kiếm chuỗi ngắn nhất:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();
Optional<T> max(Comparator<T>)
phương pháp
Phương thức này max()
sử dụng một comparator
đối tượng để so sánh tất cả các phần tử trong luồng và trả về phần tử lớn nhất. Cách thuận tiện nhất để xác định đối tượng so sánh là sử dụng hàm lambda.
Ví dụ tìm kiếm chuỗi dài nhất:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();