2015-05-21 37 views
2

我越來越知道lambda語法和刪除的對象都來的東西,逗我的腦海:當我嘗試使用的代碼的最後一行刪除對象與拉姆達

private ArrayList<Person> list = new ArrayList<>(); 

public void remove(Person person){ 
    this.list.remove(person); 
} 

public void run(){ 

    list.stream().filter(p -> p.getAge() > 15).forEach(p -> p.setAge(p.getAge() + 1)); 

    list.stream().filter(p -> p.getAge() > 15).forEach(PersonDatabase::remove);; //Syntax error 

} 

,我得到一個錯誤說該方法不是靜態的。爲什麼我不能參考我已經在的課程,但是當我使用也不是靜態的Person::getName時,它工作正常嗎?

+7

'list.removeIf(p - > p.getAge()> 15)有什麼問題;'? –

+0

@AlexisC,不會導致調用PersonDatabase.remove。 – aioobe

+3

@aioobe我知道這不是問題的主要觀點,但是'PersonDatabase.remove'只在列表中調用'remove'。我只想指出,現在這種方法是無用的,你可以直接過濾列表。 –

回答

4

爲什麼我不能引用我已經在的類?

如果remove是非靜態的,它需要一個接收器(一個調用該方法的對象)。

如果此代碼位於PersonDatabase之內,則應使用以下語法:this::remove

但是當我用Person::getName這也不是靜態的,它工作正常嗎?

這是因爲p -> p.getName()(幾乎)相當於Person::getName。自動選擇參數p作爲對Person::getName的調用的接收方。

換言之,既該變型

/* Static Person method */ static void method(Person p) { ... } 

和該變型

/* Non-static Person method */ void method() { ... } 

可以遍歷Person對象時被用作Person::method。在前一種情況下,p將作爲參數傳遞,在後一種情況下,將使用p作爲接收方。

0

PersonDatabase::remove有兩個參數 - 一個隱含的 - 當前的PersonDatabase實例,另一個顯式 - 傳入的Person實例。

因此,只有一個Person實例可用時,您不能使用此方法參考。當您將刪除方法更改爲靜態時,可以消除隱含的PersonDatabase參數,而只有一個參數Person,這會導致您的方法與forEach預期的參數相匹配。