使用lambda删除对象

时间:2015-05-21 11:00:05

标签: java lambda java-8

我开始了解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时,它也不是静态的,它可以正常工作吗?

2 个答案:

答案 0 :(得分: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::method个对象时,

可用作Person。在前一种情况下,p将作为参数传递,在后一种情况下,p将用作接收者。

答案 1 :(得分:0)

PersonDatabase::remove有两个参数 - 一个是隐式的 - 当前的PersonDatabase实例,另一个是显式的 - 传递的Person实例。

因此,只有单个Person实例可用时,才能使用此方法引用。当您将remove方法更改为静态时,可以消除隐式PersonDatabase参数,只留下一个Person参数,这会使您的方法与forEach所需的参数匹配。 / p>