我正在学习功能接口,lambda表达式和谓词的概念。我可以在互联网上使用示例编写程序,但我仍然不清楚某些结构。
这是我的班级Employee
,有3个数据成员,一个构造函数和相应的setter&吸气剂。
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;
}
}
这是另一个有3种方法可以检查的类:
一个。员工是否是男性。 湾员工是否是女性。 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;
}
}
这是我的主要课程:
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行是test()
接口的Predicate
方法的实现吗?如果是,为什么方法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而不是应用于谓词本身(如Line3中所做的那样)。如果它意味着否定Predicate
对象,那么test()
方法的o / p为什么以及如何被否定?在后台将boolean
值从true
更改为false
后会发生什么。返回的谓词对象的类型是否决定了test()方法的o / p?
4)当negate()
的返回类型也是Predicate<T>
时,Line4的o / p也是“java.util.function.Predicate$$Lambda$2/2055281021@5ca881b5” 。那么为什么isMale()
/ isFemale()
的o / p不是相同的格式?
答案 0 :(得分:4)
isMale()
是一个返回Predicate<Employee>
的方法,Employee
是一个功能接口,只有一个方法接受boolean
并返回Employee
。< / p>
该方法不会为给定的Employee
返回该布尔值。它返回一个可以应用于任何toString
的函数并返回一个布尔值。
当您打印引用变量时,您会看到该变量引用的对象的运行时类型,而不是其编译时类型(当然,这是假设运行时类型不会覆盖{{1} })。 lambda表达式是一种实现功能接口的方法。如果您使用某个类Predicate<Employee> predicate1 = new ClassThatImplementsPrdicateEmployee()
显式实现了该接口,则打印predicate1
将为您提供该类ClassThatImplementsPrdicateEmployee
的名称,而不是Predicate
。类似地,在lambda表达式的情况下,编译器生成返回的名称,类似于匿名类实例。
至于否定的内容,请查看默认实现:
default Predicate<T> negate() {
return (t) -> !test(t);
}
它返回Predicate
,其实现是对给定参数应用原始Predicate
的{{1}}方法的否定。
答案 1 :(得分:4)
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 emp -> emp.getGender().equalsIgnoreCase("Male");
实际上返回一个Predicate
,它有一个返回布尔值的测试方法。
2
当编译器看到lambda函数时,它将 de-sugare 指向实际编写此谓词的类中的实例方法。
所以在你的EmployeePredicates
中,你会有一些像这样的方法(你可以通过javap
反编译并看到它们):
private static boolean lambda$isFemale$0(Employee employee ){
// your isFemale logic here
}
然后将为您Predicate
生成一个在运行时生成的类,它将调用此方法。该类名称为:EmployeePredicates$$Lambda$1
。您可以通过以下命令再次查看此类名称和代码:
-Djdk.internal.lambda.dumpProxyClasses = / Your / Path
所以这就是类来自的地方,名称由编译器生成。
3
基本上是!=
代替Predicate
的{{1}}。如果你看一下==
的实现,这应该是明确的:
negate
应用测试,然后否定结果。
答案 2 :(得分:1)
1) 无论何时使用lambda,都要创建函数。在这种情况下,您指定该函数应为Predicate类型。由于Interface Predicate只有一种方法可以实现,因此&#39; - &gt;&#39;是该功能的实现。
2) println将调用该对象上的toString(),该对象是Predicate对象。 Lamdas将有一个toString方法的默认实现,种类可以帮助您找到它的创建位置。
3) .negate()将创建一个全新的谓词,而后者又可以进行测试。它将返回相反的值。