【问题标题】:Iterating over List in Java8 [duplicate]在Java8中迭代列表[重复]
【发布时间】:2014-07-05 06:38:42
【问题描述】:

我已经看到了在 java8 中迭代列表的两种不同方法。

案例一:

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 使用方法参考 ::

谁能解释一下这两种情况?

【问题讨论】:

  • 那么您目前对它们有什么不了解的地方?你了解 lambdas、方法引用和函数式接口吗?如果没有,那将是第一组要研究的主题......

标签: java foreach java-8


【解决方案1】:

首先你需要知道forEach是如何定义的:

void forEach(Consumer<? super T> action)

文档说明默认实现的行为如下:

for (T t : this)
    action.accept(t);

一个Consumer&lt;T&gt; 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&lt;Person&gt;的动作,那么它可以像这样使用/调用:

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&lt;T&gt; 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)

【讨论】:

    【解决方案2】:

    lambda 表达式是一种匿名方法:一段可以被调用的代码。

    案例 1:ListforEach 方法将为列表中的每个元素调用 lambda 表达式。每次调用 lambda 时,name 都会引用列表中被调用的元素。

    案例 2:除了匿名方法(lambda 表达式),您还可以传递对现有命名方法的引用,在本例中为 System.outprintln 方法。现在,forEach 将为列表中的每个元素调用该方法。请注意,name 参数现在未明确提及。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 2019-09-11
      • 2018-04-26
      • 2019-06-26
      • 2020-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多