我非常熟悉java.util.Scanner
使用next()
,hasNext()
,nextInt()
,nextLine()
等来解析输入。
我还应该在Scala中使用其他东西吗?
此数据不是根据语法构建的;它比那更特别。
例如,假设我有一个库存。每行输入都以名称开头,然后是这些项目的数量,然后是那些项目的ID
Firetruck 2 A450M A451M
Machine 1 QZLT
Keyboard 0
我看到Console
有readInt()
之类的方法,但它会读取整行输入;相当于nextInt()
似乎不存在。
java.util.Scanner
显然可以解决问题。但是我还应该使用其他东西(例如,返回Scala而不是Java类型的东西)?
答案 0 :(得分:5)
没有等效的Scala实现。但我没有看到一个原因,因为java.util.Scanner可以完美地工作,并且所有java基元类型都将隐式转换为Scala类型。
对于“例如,返回Scala而不是Java类型的东西”,Scanner将在scala中使用时返回scala类型。
答案 1 :(得分:1)
使用空格和换行符表示的输入数据可以通过map
的每一行split
和input
很好地完成。
def input =
"""Firetruck 2 A450M A451M
Machine 1 QZLT
Keyboard 0"""
case class Item(name: String, quantity: Int, ids: Array[String])
scala> input.lines.map(_.split(" ")).map(split => Item(split(0), split(1).toInt, split.takeRight(2))).toList
res0: List[Item] = List(Item(Firetruck,2,[Ljava.lang.String;@6608842e), Item(Machine,1,[Ljava.lang.String;@391e1c57), Item(Keyboard,0,[Ljava.lang.String;@67d6b10c))
scala>res0.foreach(println(_))
Item(Firetruck,2,[Ljava.lang.String;@6608842e)
Item(Machine,1 [Ljava.lang.String;@391e1c57)
Item(Keyboard,0,[Ljava.lang.String;@67d6b10c)
答案 2 :(得分:1)
better-files是一个Scala库,可为java.util.Scanner
提供更快,更安全,更惯用的替换,并提供更多操作,例如偷看和扫描。
链接:https://github.com/pathikrit/better-files#scanner
代码示例:
val data = (home / "Desktop" / "stocks.tsv") << s"""
| id Stock Price Buy
| ---------------------
| 1 AAPL 109.16 false
| 2 GOOGL 566.78 false
| 3 MSFT 39.10 true
""".stripMargin
val scanner: Scanner = data.newScanner.skip(lines = 2)
assert(scanner.peekLine == Some(" 1 AAPL 109.16 false"))
assert(scanner.peek == Some("1"))
assert(scanner.nextInt == Some(1))
assert(scanner.peek == Some("AAPL"))
assert(scanner.nextString() == Some("AAPL"))
assert(scanner.nextInt() == None)
assert(scanner.nextDouble() == Some(109.16))
assert(scanner.nextBoolean() == Some(false))
while(scanner.hasNext) {
println(scanner.nextInt(), scanner.next(), scanner.nextDouble(), scanner.nextBoolean())
}