错误:值+ =不是Long Scala的成员

时间:2016-10-17 21:32:42

标签: scala apache-spark dataframe amazon-cloudwatch

我正在尝试进行一些聚合,以便将指标发布到Cloud watch。我在保存最终结果之前添加了我的指标计数逻辑。基本上我正试图获得有价值的客户数量>每列0。这样我就可以得到数字和百分比。

case class ItemData(totalRent : Long, totalPurchase: Long, itemTypeCounts: Map[String, Int] ) extends Serializable


import scala.collection.JavaConversions._


class ItemDataMetrics(startDate: String) {

  var totals: ItemData = _

  def countNonZero(c: Long): Int = {if (c > 0) 1 else 0}


  def accumulate(featureData: ItemData) {

    totals.totalRent+= countNonZero( featureData.totalRent )
    totals.totalPurchase += countNonZero( featureData.totalPurchase )

    for (entry <- featureData.itemTypeCounts.entrySet) {

      if (totals.itemTypeCounts.contains( entry.getKey )) {
        totals.itemTypeCounts.updated( entry.getKey, entry.getValue + countNonZero( entry.getValue ) )
      } else {
        totals.itemTypeCounts.put( entry.getKey, countNonZero( entry.getValue ) )
      }
    }
  }
}

 var totalCustomer : Int = 0
 val itemMetrics: ItemDataMetrics = new ItemDataMetrics(startDate)

 val resultValue = resultDF.map( {
      r => {
        val customerId = r.getAs[String]( "customerId" )

        val totalRent = r.getAs[Long]( "totalRent" )
        val totalPurchase = r.getAs[Long]( "totalPurchase" )


        val itemTypeCounts = r.getAs[Map[String, Int]]( "itemType" )


        val items = ItemData( totalRent, totalPurchase, itemTypeCounts)

        totalCustomer = totalCustomer + 1

        itemMetrics.accumulate(items)

        val jsonString = JacksonUtil.toJson( items)

        (customerId, jsonString)
      }
    } )

    publishMetrics(startDate, featureMetrics)   ---- publishes metrics to cloud watch

   resultValue.saveAsTextFile("S3:....")

但不断收到错误:

<console>:26: error: value += is not a member of Long
           totals.totalRent += countNonZero( itemData.totalRent )
                                    ^
<console>:27: error: value += is not a member of Long
           totals.totalPurchase += countNonZero( itemData.totalPurchase )

<console>:36: error: value entrySet is not a member of Map[String,Int]
           for (entry <- itemData.itemTypeCounts.entrySet) {

我是scala / spark的新手。有人可以告诉我这里我做错了什么吗?

2 个答案:

答案 0 :(得分:4)

在Scala中x += y有效的条件有两个:

  1. x有一个名为+=的方法,将以y作为参数调用,或者
  2. xvar,其方法名为+。在这种情况下,x将被分配x + y
  3. 的结果

    现在Long只有+方法,没有+=方法。因此,如果+=Long,您只能在var上使用ItemData。现在您没有显示totals.totalRent类的定义,但由于您收到错误,我认为valdef(或+=)。因此,它无法重新分配,您无法在其上使用{{1}}。

答案 1 :(得分:2)

在Scala中,+=通常采用可变变量(var),为其添加值,并将新值重新分配给变量。这只适用于var,因为这是一个可变变量。它不适用于val(不可变)或函数定义。

在下面一行中,totalRentval,无法重新分配。

totals.totalRent+= countNonZero( featureData.totalRent )

您可以在案例类变量定义中使用var而不是默认val来解决此问题。见下文:

case class ItemData(var totalRent : Long, var totalPurchase: Long, var itemTypeCounts: Map[String, Int] ) extends Serializable

这将允许+=重新分配。