2016-10-17 49 views
1

我正在尝试做一些用于将度量标准发布到Cloud Watch的聚合。在保存最终结果之前添加指标计数逻辑。基本上我试图让每列的值> 0的客户数。这样我可以得到数字和百分比。错误:value + =不是Long Scala的成员

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) { 

我是新来斯卡拉/火花。有人能告诉我我在这里做错了什么吗?

回答

3

有两种条件下,其x += y有效Scala中:

  1. x有一个名为+=方法,该方法将与y被称为自变量,或
  2. xvar并且具有方法名为+。在这种情况下x将被分配的x + y

结果现在Long只有一个+方法,没有+=方法。因此,如果它是var,则只能在Long上使用+=。现在您没有显示ItemData类的定义,但是由于您遇到了错误,我认为totals.totalRentval(或def)。因此它不能被重新分配,并且你不能使用+=

+0

用ItemData更新。有什么办法可以做到这一点? – Newbie

+0

@Newbie你可以制作'totalRent'和'totalPurchases''var's,但你可能想要改变你的整个方法,根本不需要突变。 – sepp2k

2

在斯卡拉,+=通常需要一个可变变量(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 

这将允许+=重新分配发生。

+0

有没有办法做到这一点? – Newbie

+0

我总共使用了var。这是错的吗 ? – Newbie

+0

我已经用建议的解决方案更新了上述内容。在您的ItemData类中,您可以将totalRent,totalPurchase和itemTypeCounts字段设置为变量。 –

相关问题