我已经看到了两种不同的方法来迭代java8中的列表。
案例1:
List<String> names = Arrays.asList("Rakesh", "Amal", "Ramez", "Sreejith");
names.forEach(name -> System.out.println(name));
案例2:
List<String> names = Arrays.asList("Rakesh", "Amal", "Ramez", "Sreejith");
names.forEach(System.out::println);
案例1是使用Lambda表达式和案例2使用方法参考::
任何人都可以解释这两个案件吗?
答案 0 :(得分:4)
首先,您需要了解forEach
的定义方式:
void forEach(Consumer<? super T> action)
文档说明默认实现的行为如下:
for (T t : this)
action.accept(t);
Consumer<T>
is a functional interface:
Represents an operation that accepts a single input argument and returns no result.
。
可以使用lambda语法调用指定的操作。如果有这样的类:
class Person
{
String Name
int Age
}
以及使用此类Consumer<Person>
的操作,然后可以像这样使用/调用它:
p -> p.Name
使用lambda syntax的第一个变体是将指定的方法(在本例中为System.out.println
)应用于参数name
。您可以将该行读作:
for each name from the list names do System.out.println(name)
第二种变体使用Consumer inerface的性质,以便将函数应用于列表的每个项,而无需明确指定参数,因为这是自动完成的(因为匹配的签名),它被称为Method Reference。
因此,这允许调用只需要一个Consumer<T>
argument的方法:
This is a functional interface whose functional method is accept(Object).
。
在这种情况下,forEach
构造恰好是一个这样的方法,这就是为什么可以从调用中省略参数name
,从而导致语法:
list.forEach(someMethodWithOneParameterOnly);
在后台,呼叫再次转换为:
for each item from list do someMethodWithOneParameterOnly(item)
答案 1 :(得分:2)
lambda表达式是一种匿名方法:可以调用的一段代码。
案例1:forEach
的{{1}}方法将为列表中的每个元素调用lambda表达式。每次调用lambda时,List
都会引用列表中要求它的元素。
案例2:您也可以将引用传递给现有的命名方法,而不是匿名方法(lambda表达式),在这种情况下是name
println
方法。现在,System.out
将为列表中的每个元素调用该方法。请注意,现在未明确提及forEach
参数。