Tôi đang xem qua mã sử dụng Predicate
trong Java. Tôi chưa bao giờ sử dụng Predicate
. Ai đó có thể hướng dẫn tôi bất kỳ hướng dẫn hoặc giải thích khái niệm nào Predicate
và việc triển khai nó trong Java không?
Predicate
Tôi đang xem qua mã sử dụng Predicate
trong Java. Tôi chưa bao giờ sử dụng Predicate
. Ai đó có thể hướng dẫn tôi bất kỳ hướng dẫn hoặc giải thích khái niệm nào Predicate
và việc triển khai nó trong Java không?
Predicate
Câu trả lời:
Tôi cho rằng bạn đang nói đến com.google.common.base.Predicate<T>
từ Guava.
Từ API:
Xác định một
true
hoặcfalse
giá trị cho một đầu vào nhất định. Ví dụ: aRegexPredicate
có thể triển khaiPredicate<String>
và trả về true cho bất kỳ chuỗi nào phù hợp với biểu thức chính quy đã cho của nó.
Đây thực chất là một bản tóm tắt OOP cho một boolean
bài kiểm tra.
Ví dụ: bạn có thể có một phương thức trợ giúp như thế này:
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
Bây giờ, với một List<Integer>
, bạn chỉ có thể xử lý các số chẵn như sau:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for (int number : numbers) {
if (isEven(number)) {
process(number);
}
}
Với Predicate
, if
bài kiểm tra được tóm tắt dưới dạng một kiểu. Điều này cho phép nó tương tác với phần còn lại của API, chẳng hạn như API Iterables
có nhiều phương thức tiện ích Predicate
.
Vì vậy, bây giờ bạn có thể viết một cái gì đó như sau:
Predicate<Integer> isEven = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return (number % 2) == 0;
}
};
Iterable<Integer> evenNumbers = Iterables.filter(numbers, isEven);
for (int number : evenNumbers) {
process(number);
}
Lưu ý rằng giờ đây vòng lặp for-each đơn giản hơn nhiều mà không cần if
kiểm tra. Chúng tôi đã đạt đến cấp độ rút ngắn cao hơn bằng cách xác định Iterable<Integer> evenNumbers
, bằng filter
cách sử dụng a Predicate
.
Iterables.filter
Predicate
cho phép Iterables.filter
phục vụ như những gì được gọi là một hàm bậc cao hơn. Riêng nó, điều này mang lại nhiều lợi thế. Lấy List<Integer> numbers
ví dụ trên. Giả sử chúng ta muốn kiểm tra xem tất cả các số đều dương. Chúng ta có thể viết một cái gì đó như thế này:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
Với Predicate
và tương tác với phần còn lại của các thư viện, thay vào đó chúng ta có thể viết như sau:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
Hy vọng rằng bây giờ bạn có thể thấy giá trị trong các quy trình trừu tượng cao hơn cho các quy trình như "lọc tất cả các phần tử theo vị từ đã cho", "kiểm tra xem tất cả các phần tử có thỏa mãn vị từ đã cho hay không", v.v. để tạo mã tốt hơn.
Thật không may, Java không có các phương thức hạng nhất: bạn không thể chuyển các phương thức xung quanh đến Iterables.filter
và Iterables.all
. Tất nhiên, bạn có thể truyền xung quanh các đối tượng trong Java. Do đó, Predicate
kiểu được xác định và bạn chuyển các đối tượng triển khai giao diện này thay thế.
Predicate<Integer>
khi chúng ta đã có F<Integer, Boolean>
cái nào làm được điều tương tự?
Vị từ là một hàm trả về giá trị true / false (tức là boolean), trái ngược với mệnh đề là giá trị true / false (tức là boolean). Trong Java, người ta không thể có các hàm độc lập, và vì vậy người ta tạo một vị từ bằng cách tạo một giao diện cho một đối tượng đại diện cho một vị từ và sau đó người ta cung cấp một lớp thực hiện giao diện đó. Ví dụ về giao diện cho một vị từ có thể là:
public interface Predicate<ARGTYPE>
{
public boolean evaluate(ARGTYPE arg);
}
Và sau đó bạn có thể có một triển khai như:
public class Tautology<E> implements Predicate<E>
{
public boolean evaluate(E arg){
return true;
}
}
Để hiểu rõ hơn về khái niệm, bạn có thể muốn đọc về logic bậc nhất.
Chỉnh sửa
Có một giao diện Predicate chuẩn ( java.util. Chức năng.Predicate ) được định nghĩa trong Java API của Java 8. Trước Java 8, bạn có thể thấy thuận tiện khi sử dụng lại giao diện com.google.common.base.Predicate từ Ổi .
Ngoài ra, lưu ý rằng kể từ Java 8, việc viết các vị từ bằng cách sử dụng lambdas đơn giản hơn nhiều. Ví dụ, trong Java 8 trở lên, người ta có thể truyền p -> true
cho một hàm thay vì xác định một lớp con Tautology được đặt tên như trên.
Bạn có thể xem các ví dụ về java doc hoặc ví dụ về cách sử dụng Predicate tại đây
Về cơ bản, nó được sử dụng để lọc các hàng trong tập kết quả dựa trên bất kỳ tiêu chí cụ thể nào mà bạn có thể có và trả về true cho những hàng đáp ứng tiêu chí của bạn:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
Bổ sung vào những gì Micheal đã nói:
Bạn có thể sử dụng Predicate như sau để lọc các bộ sưu tập trong java:
public static <T> Collection<T> filter(final Collection<T> target,
final Predicate<T> predicate) {
final Collection<T> result = new ArrayList<T>();
for (final T element : target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
một vị từ khả dĩ có thể là:
final Predicate<DisplayFieldDto> filterCriteria =
new Predicate<DisplayFieldDto>() {
public boolean apply(final DisplayFieldDto displayFieldDto) {
return displayFieldDto.isDisplay();
}
};
Sử dụng:
final List<DisplayFieldDto> filteredList=
(List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);
Predicate
? Một cái gì đó tương tự? Một cái gì đó hoàn toàn khác?