将字符串转换为Long时的Scala NumberFormatException ?

时间:2022-09-13 11:33:04

Our app is Scala-based and built on the Play! framework. I've generated a random number using Scala Random. This is to use as a unique key for each account in our app.

我们的应用程序是基于scala的,并且是在游戏中构建的!框架。我用Scala随机生成了一个随机数。这是我们应用程序中每个帐户的唯一键。

However, when I go to save the new account into the database, it throws a java.lang.NumberFormatException:

但是,当我将新帐户保存到数据库中时,它会抛出java.lang.NumberFormatException:

More Info: I'm converting a string of an account ID to a Scala Long. I'm looking it up using a Squeryl object, grabbing the ID, and then converting it. Here's what it looks like:

更多信息:我正在将一个帐户ID字符串转换为一个Scala Long。我用一个Squeryl对象查找它,抓取ID,然后转换它。下面是它的样子:

val account_id = Account.findAccountByUnique(account.uniqueKey).id.toLong

val account_id = Account.findAccountByUnique .id.toLong(account.uniqueKey)

This is what findAccountByUnique looks like:

这就是findAccountByUnique的样子:

def findAccountByUnique(criteria: String) = {
    from(DB.accounts)(a =>
      where(a.uniqueKey == criteria)
        select (a))
  }

The stack trace on error:

错误的堆栈跟踪:

java.lang.NumberFormatException: For input string: "468b68c"
        at java.lang.NumberFormatException.forInputString(Unknown Source)
        at java.lang.Long.parseLong(Unknown Source)
        at java.lang.Long.parseLong(Unknown Source)
        at scala.collection.immutable.StringLike$class.toLong(StringLike.scala:209)
        at scala.collection.immutable.StringOps.toLong(StringOps.scala:31)
        at controllers.Accounts$.save(Accounts.scala:44)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:548)
        at play.mvc.ActionInvoker.invoke(ActionInvoker.java:502)
        at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:496)
        at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:473)
        at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
        at play.server.PlayHandler$NettyInvocation.execute(PlayHandler.java:257)
        at play.Invoker$Invocation.run(Invoker.java:278)
        at play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:235)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

I've typecasted the unique key as both a Scala Long and String but it throws the same error. Any idea as to a fix?

我将唯一的键作为Scala的长字符串和String类型进行了分类,但是它抛出了相同的错误。有什么办法吗?

3 个解决方案

#1


4  

To convert a hexadecimal number to a decimal one there is java.lang.Long.parseLong:

要将十六进制数转换为十进制数,有java.lang.Long.parseLong:

scala> import java.lang.{ Long => JLong }
import java.lang.{Long=>JLong}

scala> JLong.parseLong("468b68c", 16)
res8: Long = 73971340

Another way to convert hex to decimal, is to write your own method:

另一种将十六进制转换成十进制的方法,是编写自己的方法:

def toHex(s: String): Long = {
  val Hex = "([0-9a-fA-F]+)".r
  s match {
    case Hex(_) => java.lang.Long.parseLong(s, 16)
    case _ => throw new NumberFormatException("invalid hex number: " + s)
  }
}

#2


0  

Id is in hexadecimal, so you need

Id是十六进制,所以你需要。

val account_id = Account.findAccountByUnique(account.uniqueKey).id.toLong(16)

#3


0  

After further investigation it looks like there was a database helper returning junk data. Essentially it was actually returning its own "sample" data which happened to be a hexadecimal. It was a lib in Squeryl, looks like something was malformed somewhere and therefore it triggered a "sample" response.

经过进一步的调查,看起来有一个数据库助手返回垃圾数据。本质上,它实际上是返回自己的“样本”数据,它碰巧是十六进制。它是一个在Squeryl的lib,看起来像是在某个地方出现了故障,因此它触发了一个“样本”响应。

Looks like because account.uniqueKey had been updated from a previous query, it brought some junk with it. Still investigating how it happened but at least I found the real problem.

看起来像因为账户。uniqueKey从以前的查询中得到了更新,它带来了一些垃圾。还在调查这件事是怎么发生的,但至少我找到了真正的问题。

#1


4  

To convert a hexadecimal number to a decimal one there is java.lang.Long.parseLong:

要将十六进制数转换为十进制数,有java.lang.Long.parseLong:

scala> import java.lang.{ Long => JLong }
import java.lang.{Long=>JLong}

scala> JLong.parseLong("468b68c", 16)
res8: Long = 73971340

Another way to convert hex to decimal, is to write your own method:

另一种将十六进制转换成十进制的方法,是编写自己的方法:

def toHex(s: String): Long = {
  val Hex = "([0-9a-fA-F]+)".r
  s match {
    case Hex(_) => java.lang.Long.parseLong(s, 16)
    case _ => throw new NumberFormatException("invalid hex number: " + s)
  }
}

#2


0  

Id is in hexadecimal, so you need

Id是十六进制,所以你需要。

val account_id = Account.findAccountByUnique(account.uniqueKey).id.toLong(16)

#3


0  

After further investigation it looks like there was a database helper returning junk data. Essentially it was actually returning its own "sample" data which happened to be a hexadecimal. It was a lib in Squeryl, looks like something was malformed somewhere and therefore it triggered a "sample" response.

经过进一步的调查,看起来有一个数据库助手返回垃圾数据。本质上,它实际上是返回自己的“样本”数据,它碰巧是十六进制。它是一个在Squeryl的lib,看起来像是在某个地方出现了故障,因此它触发了一个“样本”响应。

Looks like because account.uniqueKey had been updated from a previous query, it brought some junk with it. Still investigating how it happened but at least I found the real problem.

看起来像因为账户。uniqueKey从以前的查询中得到了更新,它带来了一些垃圾。还在调查这件事是怎么发生的,但至少我找到了真正的问题。