1

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
jurh
  • 420
  • 1
  • 4
  • 17

1 Answers1

3

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)))
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
  • 1
    It's strange because it's a case class: case class PredictedResult(itemScores: Array[ItemScore], rules: Array[Rule]) extends Serializable. Then my code should be work. – jurh Jun 26 '19 at 12:26
  • I changed it from array to list and it works right now. Thanks! – jurh Jun 26 '19 at 13:10