scalapredictionio

How to print the content of a collection sequence


I want to print the contents of a collection and I've tried with the mkString method, but it gives me still not the right content of the object.

My code: package org.template

import org.apache.predictionio.controller.LServing

class Serving
  extends LServing[Query, PredictedResult] {

  override
  def serve(query: Query,
    predictedResults: Seq[PredictedResult]): PredictedResult = {

    println(predictedResults.mkString("\n"))
    predictedResults.head
  }

}

The response:

predictedResult([Lorg.template.ItemScore;@2fb3a837,[Lorg.template.Rule;@5cfc70a8)

Definition of the PredictedResult class:

package org.template

import org.apache.predictionio.controller.EngineFactory
import org.apache.predictionio.controller.Engine

// Query most similar (top num) items to the given
case class Query(items: Set[String], num: Int) extends Serializable

case class PredictedResult(itemScores: Array[ItemScore], rules: Array[Rule]) extends Serializable

Solution

  • If PredictedResult is a case class like so

      case class PredictedResult(value: String)
      val predictedResults = List(PredictedResult("aaa"), PredictedResult("bbb"))
      println(predictedResults.mkString("\n"))
    

    then we get nice output

    PredictedResult(aaa)
    PredictedResult(bbb)
    

    However if it is a regular class like so

      class PredictedResult(value: String)
      val predictedResults = List(new PredictedResult("aaa"), new PredictedResult("bbb"))
      println(predictedResults.mkString("\n"))
    

    then we get

    example.Hello$PredictedResult@566776ad
    example.Hello$PredictedResult@6108b2d7
    

    To get the nice output for regular class we need to override its toString method like so

      class PredictedResult(value: String) {
        override def toString: String = s"""PredictedResult($value)"""
      }
    

    which now outputs

    PredictedResult(aaa)
    PredictedResult(bbb)
    

    Addressing the comment we have

      case class Rule(v: String)
      case class ItemScore(v: Int)
      case class PredictedResult(itemScores: Array[ItemScore], rules: Array[Rule]) {
        override def toString: String =
          s"""
            |PredictedResult(Array(${itemScores.mkString(",")}, Array(${rules.mkString(",")}))
          """.stripMargin
      }
      val predictedResults = List(PredictedResult(Array(ItemScore(42), ItemScore(11)), Array(Rule("rule1"), Rule("rule2"))))
      println(predictedResults.mkString("\n"))
    

    which outputs

    PredictedResult(Array(ItemScore(42),ItemScore(11), Array(Rule(rule1),Rule(rule2)))
    

    If we change from Array to List like so

      case class Rule(v: String)
      case class ItemScore(v: Int)
      case class PredictedResult(itemScores: List[ItemScore], rules: List[Rule])
      val predictedResults = List(PredictedResult(List(ItemScore(42), ItemScore(11)), List(Rule("rule1"), Rule("rule2"))))
      println(predictedResults.mkString("\n"))
    

    then we get nice output out-of-the-box without the need to override toString

    PredictedResult(List(ItemScore(42), ItemScore(11)),List(Rule(rule1), Rule(rule2)))