2015-05-21 140 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预期的参数相匹配。