for循环使用JAVA中的lambda表达式

时间:2014-06-25 02:17:30

标签: java foreach lambda java-8

我的代码:

List<Integer> ints = Stream.of(1,2,4,3,5).collect(Collectors.toList());
ints.forEach((i)-> System.out.print(ints.get(i-1)+ " "));

out put:

  

1 2 3 4 5

我的问题是为什么我必须在get方法中使用i-1? i-1会阻止边界问题吗?

下面的代码是否像for循环迭代一样?

(i)-> System.out.print(ints.get(i-1))

以上代码等于此

for(Ineger i:ints)
   System.out.print(ints.get(i));

3 个答案:

答案 0 :(得分:13)

lambda参数i获取集合中项目的值,而不是索引。您正在减去1,因为这些值恰好是一个大于其索引的值。

如果您尝试使用

List<Integer> ints = Stream.of(10,20,40,30,50).collect(Collectors.toList());
ints.forEach((i)-> System.out.print(ints.get(i-1)+ " "));

您会发现代码效果不佳。

你应该能够做到(不需要进行get通话)

ints.forEach((i)-> System.out.print(i + " "));

你的lambda和你提出的for循环不是等价的。

ints.forEach((i)-> System.out.print(ints.get(i-1)))

等同于

for(Integer i:ints)
   System.out.print(ints.get(i-1));

请注意保留-1。


回应评论:

Lambda不是循环,它们是函数(无论如何都是有效的)。在第一个示例中,forEach方法提供了循环功能。参数lambda是每次迭代时应该的参数。这相当于for循环的 body

在注释的示例中,max是提供循环行为的函数。它将迭代(执行循环)项目以找到最大值)。您提供的lambda i -> i将是身份函数。它需要一个参数并返回该对象未修改。

假设您有一个更复杂的对象,并且想要在特定成员(例如GetHighScore())上对它们进行比较。然后,您可以使用i -> i.GetHighScore()来获得得分最高的对象。

答案 1 :(得分:1)

Java中的列表索引是从0开始的。

因此:

ints.get(0) == 1;
ints.get(1) == 2;
ints.get(2) == 3;
//etc...

您为每个&#34; i&#34;调用ints.get(i-1)在哪里&#34;我&#34;等于列表中每个元素的&#34; ints&#34;。

如果你打电话给ints.get(i),那么您将获取 index 等于1,2,3,4和5的元素,并且5不会是有效索引到包含5个元素的列表中。


代码:

ints.forEach((i)-> System.out.print(ints.get(i-1)+ " "));

相当于:

for(int i : ints ) {
    System.out.print(ints.get(i-1) + " ");
}

你的例子并不等同。

答案 2 :(得分:0)

这是一个愿望,而不是解决方案!其他语言(例如NodeJS / JavaScript)具有类似的循环,该循环将两个参数传递给lambda。参数i是索引,参数j是容器中的项目(与容器类型无关)。

ints.forEach((i,j)-> System.out.print(“索引为$ {i},项目为$ {j}”,i,j));