谓词的含义和用法 Java 8
Meaning and usage of Predicates Java 8
我正在学习函数式接口、lambda 表达式和谓词的概念。我可以使用互联网上的示例编写程序,但我仍然不清楚某些结构。
这是我的 class Employee
,有 3 个数据成员、一个构造函数和相应的 setter 和 getter。
package lambdaandrelated;
public class Employee {
private String name;
private String gender;
private int age;
public Employee(String name, String gender, int age) {
super();
this.name = name;
this.gender = gender;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
这是另一个 class 有 3 种检查方法:
一个。雇员是否为男性。
b.雇员是否为女性。
C。雇员的年龄是否大于过去的年龄。
package lambdaandrelated;
import java.util.function.Predicate;
public class EmployeePredicates {
public static Predicate<Employee> isMale(){
return emp -> emp.getGender().equalsIgnoreCase("Male"); - **Line 1**
}
public static Predicate<Employee> isFemale(){
return emp -> emp.getGender().equalsIgnoreCase("Female");
}
public Predicate<Employee> isGreaterThan(Integer age){
return emp -> emp.getAge()>age;
}
}
这是我的主class:
package lambdaandrelated;
import java.util.function.Predicate;
public class EmployeeMain {
public static void main(String[] args) {
Employee emp1 = new Employee("Parul", "Female", 24);
Employee emp2 = new Employee("Kanika", "Female", 24);
Employee emp3 = new Employee("Sumit", "Male", 27);
Predicate<Employee> predicate1 = new EmployeePredicates().isGreaterThan(23);
System.out.println(predicate1); **Line2**
boolean value = predicate1.test(emp3);
System.out.println(value);
boolean value1 = predicate1.negate().test(emp3); **Line3**
System.out.println(value1);
System.out.println(predicate1.negate()); **Line4**
}
}
我的疑问:
1)第1行是Predicate
接口的test()
方法的实现吗?如果是,为什么 return 类型的方法 isMale()
是 Predicate<Employee>
而不是 boolean
?
2) 第 2 行的 o/p 即变量 'predicate1' 的值为“ lambdaandrelated.EmployeePredicates$$Lambda$1/746292446@4617c264 ”。但是变量'predicate1'的类型是Predicate<Employee>
。这里的后台发生了什么?
3) Predicate
的否定是什么意思?如果它意味着否定 boolean
o/p,那么它不应该应用于 test()
方法的 o/p 而不是应用于谓词本身(如第 3 行中所做的那样) .如果它意味着否定 Predicate
对象,那么 test()
方法的 o/p 为什么以及如何被否定?将 boolean
值从 true
更改为 false
的后台发生了什么。是谓词对象的类型 returned 决定了 test() 方法的 o/p 吗?
4) 当 negate()
的 return 类型也是 Predicate<T>
时,Line4 的 o/p 也是 "java.util.function.Predicate$$Lambda/2055281021@5ca881b5",这看起来不错。那为什么isMale()
/isFemale()
的o/p格式不一样呢?
isMale()
是一种 return 是 Predicate<Employee>
的方法,它是一个功能接口,具有接受 Employee
和 return一个boolean
.
该方法不会 return 给定 Employee
的布尔值。它 return 是一个可以应用于任何 Employee
和 return 布尔值的函数。
当你打印一个引用变量时,你看到的是该变量引用的对象的运行时类型,而不是它的编译时类型(当然,这是假设运行时类型没有覆盖toString
)。 lambda 表达式是一种实现功能接口的方法。如果您使用某些 class Predicate<Employee> predicate1 = new ClassThatImplementsPrdicateEmployee()
显式实现接口,打印 predicate1
将为您提供 class ClassThatImplementsPrdicateEmployee
而不是 Predicate
的名称。同样,对于 lambda 表达式,编译器生成 returned 名称,类似于匿名 class 实例的情况。
至于negate的作用,看默认实现:
default Predicate<T> negate() {
return (t) -> !test(t);
}
它return是一个Predicate
,其实现是对给定参数应用原始Predicate
的test()
方法的否定。
1)
每当您使用 lambda 时,您都在创建一个 函数 。在这种情况下,您指定该函数应该是 Predicate 类型。由于Interface Predicate只有一个方法要实现,'->'后面的部分是该函数的实现。
2)
println 将调用该对象上的 toString(),该对象是 Predicate 对象。 Lamdas 将有一个 toString 方法的默认实现,某种 可以帮助您找到它的创建位置。
3)
.negate() 将创建一个 全新的 谓词,它又可以被测试。它将return相反的值。
对于 1:
你可以写得略有不同,可能是有道理的:
public static Predicate<Employee> isMale() {
return new Predicate<Employee>() {
@Override
public boolean test(Employee emp) {
return emp.getGender().equalsIgnoreCase("Male");
}
};
}
boolean 必须是 Predicate#test
的 return 类型。这个结构:
return emp -> emp.getGender().equalsIgnoreCase("Male");
实际上 return 一个 Predicate
有一个 return 布尔值的测试方法。
为 2
当编译器看到一个 lambda 函数时,它将 去糖 到 class 中您实际编写此 Predicate 的实例方法。
所以在你的 EmployeePredicates
中你会有一些这样的方法(你可以通过 javap
反编译并查看它们):
private static boolean lambda$isFemale[=12=](Employee employee ){
// your isFemale logic here
}
然后class在运行时为你生成一个Predicate
调用这个方法。 class 的名字是:EmployeePredicates$$Lambda
。您可以通过 运行 您的代码再次看到此 class 名称和代码:
-Djdk.internal.lambda.dumpProxyClasses = /Your/Path
所以这就是 class 的来源,名称是由编译器生成的。
为 3
基本上是指 !=
对于 Predicate
而不是 ==
。如果你看一下 negate
的实现,这应该很清楚:
default Predicate<T> negate() {
return (t) -> !test(t);
}
应用测试,然后否定结果。
我正在学习函数式接口、lambda 表达式和谓词的概念。我可以使用互联网上的示例编写程序,但我仍然不清楚某些结构。
这是我的 class Employee
,有 3 个数据成员、一个构造函数和相应的 setter 和 getter。
package lambdaandrelated;
public class Employee {
private String name;
private String gender;
private int age;
public Employee(String name, String gender, int age) {
super();
this.name = name;
this.gender = gender;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
这是另一个 class 有 3 种检查方法:
一个。雇员是否为男性。 b.雇员是否为女性。 C。雇员的年龄是否大于过去的年龄。
package lambdaandrelated;
import java.util.function.Predicate;
public class EmployeePredicates {
public static Predicate<Employee> isMale(){
return emp -> emp.getGender().equalsIgnoreCase("Male"); - **Line 1**
}
public static Predicate<Employee> isFemale(){
return emp -> emp.getGender().equalsIgnoreCase("Female");
}
public Predicate<Employee> isGreaterThan(Integer age){
return emp -> emp.getAge()>age;
}
}
这是我的主class:
package lambdaandrelated;
import java.util.function.Predicate;
public class EmployeeMain {
public static void main(String[] args) {
Employee emp1 = new Employee("Parul", "Female", 24);
Employee emp2 = new Employee("Kanika", "Female", 24);
Employee emp3 = new Employee("Sumit", "Male", 27);
Predicate<Employee> predicate1 = new EmployeePredicates().isGreaterThan(23);
System.out.println(predicate1); **Line2**
boolean value = predicate1.test(emp3);
System.out.println(value);
boolean value1 = predicate1.negate().test(emp3); **Line3**
System.out.println(value1);
System.out.println(predicate1.negate()); **Line4**
}
}
我的疑问:
1)第1行是Predicate
接口的test()
方法的实现吗?如果是,为什么 return 类型的方法 isMale()
是 Predicate<Employee>
而不是 boolean
?
2) 第 2 行的 o/p 即变量 'predicate1' 的值为“ lambdaandrelated.EmployeePredicates$$Lambda$1/746292446@4617c264 ”。但是变量'predicate1'的类型是Predicate<Employee>
。这里的后台发生了什么?
3) Predicate
的否定是什么意思?如果它意味着否定 boolean
o/p,那么它不应该应用于 test()
方法的 o/p 而不是应用于谓词本身(如第 3 行中所做的那样) .如果它意味着否定 Predicate
对象,那么 test()
方法的 o/p 为什么以及如何被否定?将 boolean
值从 true
更改为 false
的后台发生了什么。是谓词对象的类型 returned 决定了 test() 方法的 o/p 吗?
4) 当 negate()
的 return 类型也是 Predicate<T>
时,Line4 的 o/p 也是 "java.util.function.Predicate$$Lambda/2055281021@5ca881b5",这看起来不错。那为什么isMale()
/isFemale()
的o/p格式不一样呢?
isMale()
是一种 return 是Predicate<Employee>
的方法,它是一个功能接口,具有接受Employee
和 return一个boolean
.该方法不会 return 给定
Employee
的布尔值。它 return 是一个可以应用于任何Employee
和 return 布尔值的函数。当你打印一个引用变量时,你看到的是该变量引用的对象的运行时类型,而不是它的编译时类型(当然,这是假设运行时类型没有覆盖
toString
)。 lambda 表达式是一种实现功能接口的方法。如果您使用某些 classPredicate<Employee> predicate1 = new ClassThatImplementsPrdicateEmployee()
显式实现接口,打印predicate1
将为您提供 classClassThatImplementsPrdicateEmployee
而不是Predicate
的名称。同样,对于 lambda 表达式,编译器生成 returned 名称,类似于匿名 class 实例的情况。至于negate的作用,看默认实现:
default Predicate<T> negate() { return (t) -> !test(t); }
它return是一个
Predicate
,其实现是对给定参数应用原始Predicate
的test()
方法的否定。
1) 每当您使用 lambda 时,您都在创建一个 函数 。在这种情况下,您指定该函数应该是 Predicate 类型。由于Interface Predicate只有一个方法要实现,'->'后面的部分是该函数的实现。
2) println 将调用该对象上的 toString(),该对象是 Predicate 对象。 Lamdas 将有一个 toString 方法的默认实现,某种 可以帮助您找到它的创建位置。
3) .negate() 将创建一个 全新的 谓词,它又可以被测试。它将return相反的值。
对于 1:
你可以写得略有不同,可能是有道理的:
public static Predicate<Employee> isMale() {
return new Predicate<Employee>() {
@Override
public boolean test(Employee emp) {
return emp.getGender().equalsIgnoreCase("Male");
}
};
}
boolean 必须是 Predicate#test
的 return 类型。这个结构:
return emp -> emp.getGender().equalsIgnoreCase("Male");
实际上 return 一个 Predicate
有一个 return 布尔值的测试方法。
为 2
当编译器看到一个 lambda 函数时,它将 去糖 到 class 中您实际编写此 Predicate 的实例方法。
所以在你的 EmployeePredicates
中你会有一些这样的方法(你可以通过 javap
反编译并查看它们):
private static boolean lambda$isFemale[=12=](Employee employee ){
// your isFemale logic here
}
然后class在运行时为你生成一个Predicate
调用这个方法。 class 的名字是:EmployeePredicates$$Lambda
。您可以通过 运行 您的代码再次看到此 class 名称和代码:
-Djdk.internal.lambda.dumpProxyClasses = /Your/Path
所以这就是 class 的来源,名称是由编译器生成的。
为 3
基本上是指 !=
对于 Predicate
而不是 ==
。如果你看一下 negate
的实现,这应该很清楚:
default Predicate<T> negate() {
return (t) -> !test(t);
}
应用测试,然后否定结果。