2016-10-17 47 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字段設置爲變量。 –

相關問題