Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Scala-意外的MapReduce行为-偶数平方_Java_Scala_Mapreduce_Scala Collections - Fatal编程技术网

Java Scala-意外的MapReduce行为-偶数平方

Java Scala-意外的MapReduce行为-偶数平方,java,scala,mapreduce,scala-collections,Java,Scala,Mapreduce,Scala Collections,我正在学习Scala,对一个简单的问题的输出感到困惑 求一个范围内偶数整数的平方和 代码片段1: val rangeOfNumbers = (1 to 5) val listOfNumbers = rangeOfNumbers.toList val squaresOfEvenNumbers = listOfNumbers .filter(element => element % 2 == 0) .reduce((total, element) => total+

我正在学习Scala,对一个简单的问题的输出感到困惑 求一个范围内偶数整数的平方和

代码片段1

val rangeOfNumbers = (1 to 5)
val listOfNumbers = rangeOfNumbers.toList
val squaresOfEvenNumbers = listOfNumbers
     .filter(element => element % 2 == 0)
     .reduce((total, element) => total+ (element * element))

println(squaresOfEvenNumbers)
Outputs: 18 -> which is clearly wrong

**EDIT** - Simulation:

I want to square the filtered even numbers - 2,4 and then add them to total variable

1: (total = 0, elem = 2) => 0 + (2 * 2) = 4
2. (total = 4, elem = 4) => 4 + (4 *4 ) = 20

Isn't this the expected behavior?
val rangeOfNumbers = (1 to 5)
val listOfNumbers = rangeOfNumbers.toList
val filteredEvenNumberSquaredList = listOfNumbers
    .filter(element => element % 2 == 0)
    .map(evenEle => evenEle * evenEle)
    .reduce((total, square) => total + square)

println(filteredEvenNumberSquaredList)
Outputs: 20 -> which is correct
代码片段2

val rangeOfNumbers = (1 to 5)
val listOfNumbers = rangeOfNumbers.toList
val squaresOfEvenNumbers = listOfNumbers
     .filter(element => element % 2 == 0)
     .reduce((total, element) => total+ (element * element))

println(squaresOfEvenNumbers)
Outputs: 18 -> which is clearly wrong

**EDIT** - Simulation:

I want to square the filtered even numbers - 2,4 and then add them to total variable

1: (total = 0, elem = 2) => 0 + (2 * 2) = 4
2. (total = 4, elem = 4) => 4 + (4 *4 ) = 20

Isn't this the expected behavior?
val rangeOfNumbers = (1 to 5)
val listOfNumbers = rangeOfNumbers.toList
val filteredEvenNumberSquaredList = listOfNumbers
    .filter(element => element % 2 == 0)
    .map(evenEle => evenEle * evenEle)
    .reduce((total, square) => total + square)

println(filteredEvenNumberSquaredList)
Outputs: 20 -> which is correct

你能解释一下第一种方法的错误吗?内部发生了什么?

使用
reduce
时,倍增不会应用于第一个元素:

List(2, 4).reduce((sum, el) => sum + el * el)
=> 2 + 4 * 4
=> 18
reduce
(对于非空列表)应满足:

l.reduce(op) == l.tail.foldLeft(l.head)(op)

使用
reduce
时,倍增不会应用于第一个元素:

List(2, 4).reduce((sum, el) => sum + el * el)
=> 2 + 4 * 4
=> 18
reduce
(对于非空列表)应满足:

l.reduce(op) == l.tail.foldLeft(l.head)(op)

第一次调用传递给
.reduce
的lambda时,
total
是列表的第一个元素,
元素
是第二个元素。你不求前者的平方,只求后者的平方,所以你的结果相差2

您可能想考虑使用<代码> .FoLDLeW而不是<代码>减少< /C> >:

  list.foldLeft(0) { case (sum, elem) => sum + elem*elem }
它与
.reduce
相同,只是它以您提供的值开始(在本例中为
0
),并以相同的方式调用列表中的每个元素,包括第一个元素(它也适用于空列表,而
.reduce
会崩溃)

或者,只需
list.map(x=>x*x).sum

顺便说一句,您可以对范围本身执行所有过滤/映射等操作-无需首先将其转换为列表:

 val squaresOfEvenNumbers = (1 to 5)
   .collect { case x if x % 2 == 0 => x*x }
   .sum

第一次调用传递给
.reduce
的lambda时,
total
是列表的第一个元素,
元素
是第二个元素。你不求前者的平方,只求后者的平方,所以你的结果相差2

您可能想考虑使用<代码> .FoLDLeW而不是<代码>减少< /C> >:

  list.foldLeft(0) { case (sum, elem) => sum + elem*elem }
它与
.reduce
相同,只是它以您提供的值开始(在本例中为
0
),并以相同的方式调用列表中的每个元素,包括第一个元素(它也适用于空列表,而
.reduce
会崩溃)

或者,只需
list.map(x=>x*x).sum

顺便说一句,您可以对范围本身执行所有过滤/映射等操作-无需首先将其转换为列表:

 val squaresOfEvenNumbers = (1 to 5)
   .collect { case x if x % 2 == 0 => x*x }
   .sum

奇怪的是,为什么平方不适用于第一个元素?这是故意的吗?@aces。这就是
reduce
的工作方式。您没有像在
foldLeft
/
foldRight
中那样提供初始元素,它需要从某个地方开始,以便它抓住集合中的第一个元素并从该元素开始。奇怪的是,为什么平方不应用于第一个元素?这是故意的吗?@aces。这就是
reduce
的工作方式。您没有像在
foldLeft
/
foldRight
中那样提供初始元素,它需要从某个地方开始,这样它才能抓住集合中的第一个元素并从该元素开始。我不确定您所说的“不平方前者,只平方后者,因此,你的结果是2'我想平方过滤后的偶数-2,4,然后将它们添加到总变量1:(total=0,elem=2)=>0+(2*2)=42。(total=4,elem=4)=>4+(4*4)=20这不是预期的行为吗?好吧,它不是
(total=0,elem=2)
在第一次调用时,它是
(total=2,elem=4)
-这就是问题所在。我明白了,你说的是reduce函数使用第一个元素,即2作为初始总值,然后应用函数。因此,有效地,只进行了一次传递,即:reduce((2,4)=>2+4*4)=18。谢谢你的意见!我不知道你所说的“你不求前者的平方,只求后者的平方,所以你的结果是2”是什么意思。我想把过滤后的偶数-2,4平方,然后把它们加到总变量1中:(total=0,elem=2)=>0+(2*2)=42。(total=4,elem=4)=>4+(4*4)=20这不是预期的行为吗?好吧,它不是
(total=0,elem=2)
在第一次调用时,它是
(total=2,elem=4)
-这就是问题所在。我明白了,你说的是reduce函数使用第一个元素,即2作为初始总值,然后应用函数。因此,有效地,只进行了一次传递,即:reduce((2,4)=>2+4*4)=18。谢谢你的意见!是什么让您期望第一次呼叫时的
总数
为0?您没有将
0
传递到
reduce
任何位置。。。它怎么可能猜出你的意思?我做了一个假设,它会初始化为零。错误的假设它看起来像是什么让你期望第一次调用的
总数
为0?您没有将
0
传递到
reduce
任何位置。。。它怎么可能猜出你的意思?我做了一个假设,它会初始化为零。这似乎是个错误的假设