2017-02-19 5 views
-1

com.google.gson.JsonObjectをcaseクラスオブジェクトに変換しようとしています。いつかあなたの場合、私はクラスのメンバを小文字ために、それはなしとして割り当てることがしたい場合は、レコード内のいくつかの要素欠けているスカラ条件なし値の割り当て

object tmp { 
    case class person(name: String, age: Long) 
    def main(args: Array[String]): Unit = { 
    val parser = new JsonParser(); 

    //PERSON 2 
    val record2 = parser.parse("""{"name":"xyz"}""").getAsJsonObject() 

    val record2_name = record2.get("name").getAsString.toLowerCase 
    val record2_age = if(record2.get("age") != null) record2.get("age") else None 

    val person2 = new person(record2_name,record2_age) //-> Type Mismatch, expected: Long, actual: Long 

    println(person2); 

    } 
} 

答えて

0

record2_ageは、単純型のJava ObjectのあるタイプJsonElementのですが、あるので、それにNoneを割り当てるとLongに割り当てようとしているのはAnyになります。短い答えは次のようになり

val person = new person(jsonObject.get("name").getAsString.toLowerCase, 
    Option(jsonObject.get("age")).map(_.getAsLong).getOrElse(0l)) 

この方法jsonObject.get("age")がnullの場合、Option(null)はあなたにNoneを与える、またはあなたが= Some(28)

Option(28)を得る存在する場合は、おそらくあなたの年齢が空の場合0lになりたいです。 Noneにしたい場合は、Option[Long]を使用できます。

1)簡単な方法

class GsonCaseClassSpecs extends FunSpec { 

    describe("case class conversion") { 

    it("converts gson with name/age to case class") { 

     case class person(name: String, age: Long) 

     val parser = new JsonParser() 

     //case 1 
     val jsonObject : JsonObject = parser.parse("""{"name":"xyz"}""").getAsJsonObject 

     val age = jsonObject.get("age") match { 
     case null => None 
     case value => Some(value.getAsLong) 
     } 

     val person1 = new person(jsonObject.get("name").getAsString.toLowerCase, age.getOrElse(0l)) 

     assert(person1.name == "xyz") 
     assert(person1.age == 0) 

     //case 2 
     val jsonObject2 : JsonObject = parser.parse("""{"name":"xyz", "age" : 28}""").getAsJsonObject 

     val age2 : Option[Long] = jsonObject2.get("age") match { 
     case null => None 
     case value => Some(value.getAsLong) 
     } 

     val person2 = new person(jsonObject2.get("name").getAsString.toLowerCase, age2.getOrElse(0l)) 

     assert(person2.name == "xyz") 
     assert(person2.age == 28) 
    } 

    } 
} 

2)あなたは年齢がOption[Long]するようにしたい場合。Option[T]は、Some(x)またはNoneを持つことができます。

class CaseClassFunSpecs extends FunSpec { 

it("converts json to case class with empty age"){ 

    case class person(name: String, age: Option[Long]) 

    val parser = new JsonParser() 

    val json = parser.parse("""{"name":"xyz"}""").getAsJsonObject() 

    val personInstance = new person(json.get("name").getAsString.toLowerCase, 
    Option(json.get("age")).map(_.getAsLong)) 

    assert(personInstance.name == "xyz") 
    assert(personInstance.age == None) 
    // NOTE 
    // do not do personInstance.age.get which would throw 
    // None.get 
    // java.util.NoSuchElementException: None.get 
    // at scala.None$.get(Option.scala:347) 
    // at scala.None$.get(Option.scala:345) 

    //rather use pattern match 
    personInstance.age match { 
    case Some(x) => println("value = " + x) 
    case None => throw new RuntimeException("Age can not be empty.") 
    } 
    } 

it("converts json to case class with non-empty age"){ 

    case class person(name: String, age: Option[Long]) 

    val parser = new JsonParser() 

    val json = parser.parse("""{"name":"xyz", "age" : 28}""").getAsJsonObject() 

    val personInstance = new person(json.get("name").getAsString.toLowerCase, 
    Option(json.get("age")).map(_.getAsLong)) 

    assert(personInstance.name == "xyz") 
    assert(personInstance.age == Some(28)) 
    assert(personInstance.age.get == 28) //.get gives you the value 
} 
} 
+0

0として、この設定された年齢かもしれません。この要素が行にないことを示すために何かが必要です。 – xstack2000

+0

@ xstack2000その場合、 'Option [Long]'が必要です。更新された回答を参照してください。それが役に立ったら教えてください。 – prayagupd

+0

@ xstack2000も 'ageOption'を使っているときにNOTEを読んでいます。' None'の '.get'は例外を投げます。 – prayagupd

1

あなたは、単に異なるタイプOption[Long]の引数で、あなたのケースでは1種類、age: Longのパラメータを呼び出すことはできません。

少なくともこれはあなたの質問が示唆しているようです。

欠損する可能性がある属性をOptionに定義する必要があります。

あなたの例では

case class person(name: String, age: Option[Long]) 

、あなたは引数がある場合Noneを返しますがOption.apply方法を利用することができますJSON値を抽出する場合、その後null

… 
val record2_age = Option(record2.get("age")).map(_.getAsLong) // None if get("age) returns null 
… 
val person2 = new person(record2_name,record2_age) //There should be no more type mismatch now 
+0

私は試しましたが、それでもまだ仕事はしませんでした val person2 =新しい人//タイプミスマッチ、期待値:Option [Long]、実際:オプション[jsonElement] – xstack2000

+0

回答を@ prayagupdの答えは、今すぐ試してください –

関連する問題