Сканер в Скале

Я хотел реализовать Java Scanner в Scala. Целью этого класса является:

  1. Внедрить интерфейс коллекции Scala (возможно, Iterator[String]?), поэтому я могу получить доступ ко всем коллекциям коллекции Scala, например map, .toList и т. Д.
  2. более высокая производительность , чем java.util.Scanner

Прочитайте мой код для получения советов по ошибкам /советам по дизайну:

import java.io._
import java.util.StringTokenizer
/**
 * Scala implementation of a faster java.util.Scanner
 * See: http://codeforces.com/blog/entry/7018
 */
class Scanner(reader: BufferedReader) extends Iterator[String] {
  def this(inputStreamReader: InputStreamReader) = this(new BufferedReader(inputStreamReader))
  def this(file: File) = this(new FileReader(file))
  def this(inputStream: InputStream) = this(new InputStreamReader(inputStream))
  def this(str: String) = this(new ByteArrayInputStream(str.getBytes))

  private[this] var tokenizer: StringTokenizer = _

  private[this] def nextTokenizer() = {
    while(tokenizer == null || !tokenizer.hasMoreTokens) tokenizer = new StringTokenizer(reader.readLine())
    tokenizer
  }

  def nextLine() = {
    tokenizer = null
    reader.readLine()
  }

  override def hasNext = nextTokenizer().hasMoreTokens

  override def next() = nextTokenizer().nextToken()

  def nextInt() = next().toInt
  def nextLong() = next().toLong
  def nextDouble() = next().toDouble
}

Тесты здесь

11 голосов | спросил pathikrit 6 AM000000120000004431 2015, 00:11:44

1 ответ


9

Хотя я бы не сказал, что код ужасен, есть, конечно, несколько областей, которые можно было бы очистить. Я не буду публиковать модифицированный код, потому что я думаю, что есть области, где «правильная вещь» будет зависеть от предполагаемого использования.

Прежде всего, ваше описание подразумевает, что это будет использоваться как класс библиотеки в вашем коде. Библиотечный код следует придерживаться более высокого стандарта, чем другой код, и более высокий стандарт, безусловно, означает правильную документацию, включая полную версию ScalaDoc и объявленные типы возврата для всех общедоступных методов. Правильный набор тестов также будет хорошим. Вы поблагодарите себя позже.

Во-вторых, проблема в nextTokenizer - она ​​наивно сохраняет строки чтения из читателя без проверки на нуль (т.е. конец состояния файла). Этот тестовый код покажет вам, что я имею в виду:

object ScannerTest {
  def main(args: Array[String]) {
    val test = new Scanner("ab cd")
    test.foreach((s) => println("[ScannerTest$.main] " + s))
  }
}

Фиксация этого потребует некоторой мысли о том, что должен делать код, но текущая реализация hasNext() будет иметь для изменения в любом случае. Некоторые сказали бы, что nextTokenizer() должен возвращать Option[StringTokenizer] а затем hasNext() будет выглядеть примерно так, как показано ниже. Обратите внимание: если мы получим токенизатор, мы знаем, что он имеет токены, потому что nextTokenizer() проверяет это и выбрасывает пустые строки.

def hasNext: Boolean = nextTokenizer() match {
  case None => false
  case Some(t) => true
}

Но в этот момент он должен использовать правильную икону Scala и просто сделать это.

def hasNext: Boolean = nextTokenizer().nonEmpty

Кроме того, необходимо переопределить методы «следующего» значения. В настоящее время nextLine() вернет значение null в конце файла, а остальное вызовет исключение. Ничто из этого не кажется хорошей идеей.

Наконец, я задаюсь вопросом о конструкторе, который принимает String. Казалось бы, проще использовать StringReader. Теперь код: строка, преобразованная в байты, завернутая в поток, цепочка ко второму конструктору, где она обернута в считыватель входного потока, привязывается к третьему конструктору, где она завершается в буферизованный читатель, где она, наконец, конструктор по умолчанию.

Возможно, JIT-компилятор JIT уменьшит любой подход к чему-то эквивалентному, но я думаю, что что-то вроде кода ниже будет легче следовать.

def this(str: String) = this(new BufferedReader(new StringReader(str)))
ответил Donald.McLean 20 +03002015-10-20T16:25:52+03:00312015bEurope/MoscowTue, 20 Oct 2015 16:25:52 +0300 2015, 16:25:52

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132