[英]Clarifying how Lambda expression works in the official Java tutorial
我已經一遍又一遍地閱讀了本教程 ,但我只是不了解方法6的最后一部分。
特別是這部分:
public static void printPersonsWithPredicate(
List<Person> roster, Predicate<Person> tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
因此,以下方法調用與您在方法3中調用printPersons時相同:在本地類中指定搜索條件代碼以獲取符合選擇服務資格的成員:
printPersonsWithPredicate(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
因此,如果p是泛型類型,它怎么知道它是一個Person? 我只是不知道如何區分自己作為一個人,然后調用Person方法-getGender()和getAge()。 在這種情況下,p是否引用周圍類的類對象?
更新:
根據提供的答案,這正確嗎?
如下代碼:
interface CheckPerson {
boolean test(Person p);
}
class CheckPersonEligibleForSelectiveService implements CheckPerson {
public boolean test(Person p) {
return p.gender == Person.Sex.MALE &&
p.getAge() >= 18 &&
p.getAge() <= 25;
}
}
public static void printPersons(
List<Person> roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
printPersons(roster, new CheckPersonEligibleForSelectiveService());
是相同的:
import java.util.function // import the Predicate<T> interface
public static void printPersonsWithPredicate(
List<Person> roster, Predicate<Person> tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
printPersonsWithPredicate(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
因為:
如果我錯了,請告訴我,以便我能更新我的理解。 我真的很想解決這個問題。
lambda表達式是Predicate<Person>#test
主體的定義,該主體將Person
作為參數。 我們知道這printPersonsWithPredicate
是因為printPersonsWithPredicate
被聲明為采用Predicate<Person>
,該lambda作為參數傳遞給它。
lambda的語法是->
的左側是所定義方法的參數列表:
(Person p) -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
但是,編譯器能夠確定lambda的奇異參數p
必須是Person,因此可以將其省略。 因此,縮寫形式p -> ...
在方法#4中顯示了一個與lambda幾乎等效的匿名類。
通常: 僅從相關功能接口的類型簽名中推斷出參數,包括對泛型參數的任何其他限制 。
在這種情況下,我們知道第二個參數是Predicate<T>
。 由於Predicate<T>
是方法test(T t)
的函數接口,因此我們知道p
的類型為T
(而不是Predicate<T>
)。
而且由於T
由printPersonsWithPredicate(List<Person> roster, Predicate<Person> tester)
的簽名限制為Person
,因此 p
的實際類型為Person
。
RE:UPDATE-答案既是“是”又是“否” :)。
“是”,通常可以以這種方式描述類型推斷的順序。
“否”,原因如下:
T
的類型限制為Person
。 類型人就是所允許的“公共分母”。 例如:如果方法的簽名將包含:
Predicate<? extends JLabel>
Predicate<? extends JLabel>
-那么參數類型實際上是JLabel
。 Predicate<?>
-那么參數類型實際上是Object
。 僅解決UPDATE問題...
1)謂詞接口已在java.util.function中定義
正確
2)通過在方法參數中聲明謂詞為“人”:
不正確。
您實際上是將tester
聲明為Predicate<Person>
。 您根本沒有在這里聲明Predicate
。 Predicate
是標准庫聲明的標准接口。
2a)我們正在隱式地實現帶有Person類型的謂詞
正確...有點。 您正在明確實現它。 並且這里所需的lambda的類型是由printPersonsWithPredicate
的方法簽名顯式指定的。 具體來說,因為您聲明形式參數tester
類型為Predicate<Person>
。
2b)調用具有通用類型T(或缺少通用類型T)的方法時,該類型被方法隱式推斷為Person
在這種情況下不行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.