По сути, они лошади для курсов.
Scanner
Предназначено для случаев, когда нужно разобрать строку, извлекая данные разных типов. Он очень гибкий, но, возможно, не дает вам простейшего API для простого получения массива строк, ограниченных определенным выражением.
String.split()
и Pattern.split()
дать вам простой синтаксис для выполнения последнего, но это по сути все, что они делают. Если вы хотите проанализировать результирующие строки или изменить разделитель на полпути в зависимости от конкретного токена, они вам не помогут.
StringTokenizer
это еще более ограничительно, чем использование String.split()
, и немного более неудобно. Он по сути предназначен для извлечения токенов, ограниченных фиксированными подстроками. Из-за этого ограничения это примерно в два раза быстрее String.split()
. (См. Мое сравнение String.split()
иStringTokenizer
.) Это также предшествует API регулярных выражений, частью которого String.split()
является.
По моим String.split()
временам вы заметите, что на обычной машине можно по-прежнему токенизировать тысячи строк за несколько миллисекунд . Кроме того, он имеет преимущество перед StringTokenizer
тем, что дает вывод в виде строкового массива, который обычно является тем, что вы хотите. Использование Enumeration
, как предусмотрено StringTokenizer
, в большинстве случаев слишком «синтаксически суетливо». С этой точки зрения StringTokenizer
в наше время это пустая трата пространства, и вы можете просто использовать String.split()
.
StringTokenizer
лучший выбор, потомуString.split()
что просто не хватит памяти?Давайте начнем с устранения
StringTokenizer
. Он стареет и даже не поддерживает регулярные выражения. В его документации говорится:Итак, давайте выбросим это прямо сейчас. Это оставляет
split()
иScanner
. Какая разница между ними?Во-первых,
split()
просто возвращает массив, что упрощает использование цикла foreach:Scanner
построен больше как поток:или
(У него довольно большой API , поэтому не думайте, что он всегда ограничен такими простыми вещами.)
Этот интерфейс в стиле потока может быть полезен для анализа простых текстовых файлов или ввода с консоли, когда у вас нет (или вы не можете получить) всех вводимых данных перед началом анализа.
Лично я могу вспомнить только один раз, когда использовал
Scanner
школьные проекты, когда мне приходилось получать пользовательский ввод из командной строки. Это делает такую операцию легкой. Но если у меня есть то,String
что я хочу разделить, это почти легкое делоsplit()
.источник
Scanner
для обнаружения новых символов строки в заданномString
. Поскольку символы новой строки могут варьироваться от платформы (посмотрите наPattern
Javadoc «s!) И строку ввода не гарантируют соответствиеSystem.lineSeparator()
, я считаюScanner
более подходящим , как он уже знает , что символы новой строки искать при вызовеnextLine()
. Потому чтоString.split
мне придется ввести правильный шаблон регулярных выражений, чтобы обнаружить разделители строк, которые я не нахожу хранящимися ни в одном стандартном месте (лучшее, что я могу сделать, это скопировать его изScanner
источника класса).StringTokenizer всегда был там. Это самый быстрый из всех, но идиома, похожая на перечисление, может выглядеть не так элегантно, как другие.
Сплит появился на JDK 1.4. Медленнее, чем токенизатор, но проще в использовании, так как он вызывается из класса String.
Сканер пришел на JDK 1.5. Он является наиболее гибким и заполняет давнишний пробел в Java API для поддержки эквивалента известного семейства функций Cs scanf.
источник
Если у вас есть объект String, который вы хотите токенизировать, используйте метод разделения String вместо StringTokenizer . Если вы анализируете текстовые данные из источника вне вашей программы, например из файла или от пользователя, то здесь вам пригодится сканер.
источник
Сплит медленный, но не такой медленный, как сканер. StringTokenizer быстрее, чем сплит. Однако я обнаружил, что могу получить двойную скорость, торгуя некоторой гибкостью, чтобы получить повышение скорости, что я и сделал на JFastParser https://github.com/hughperkins/jfastparser
Тестирование на строке, содержащей миллион дублей:
источник
String.split, кажется, намного медленнее, чем StringTokenizer. Единственным преимуществом split является то, что вы получаете массив токенов. Также вы можете использовать любые регулярные выражения в split. org.apache.commons.lang.StringUtils имеет метод split, который работает намного быстрее, чем любой из двух, а именно. StringTokenizer или String.split. Но загрузка ЦП для всех трех почти одинакова. Поэтому нам также нужен метод, который требует меньше ресурсов процессора, но я до сих пор не могу его найти.
источник
Недавно я провел несколько экспериментов по поводу плохой производительности String.split () в ситуациях с высокой производительностью. Вы можете найти это полезным.
http://eblog.chrononsystems.com/hidden-evils-of-javas-stringsplit-and-stringr
Суть в том, что String.split () каждый раз компилирует шаблон регулярного выражения и, таким образом, может замедлить вашу программу по сравнению с тем, если вы используете предварительно скомпилированный объект Pattern и используете его напрямую для работы со строкой.
источник
Для сценариев по умолчанию я бы также предложил Pattern.split (), но если вам нужна максимальная производительность (особенно на Android, все протестированные мной решения работают довольно медленно) и вам нужно разделить только на один символ, я теперь использую свой собственный метод:
Используйте «abc» .toCharArray (), чтобы получить массив char для String. Например:
источник
Одно важное отличие состоит в том, что и String.split (), и Scanner могут создавать пустые строки, но StringTokenizer никогда этого не делает.
Например:
Вывод:
Это связано с тем, что разделитель для String.split () и Scanner.useDelimiter () является не просто строкой, а регулярным выражением. Мы можем заменить разделитель "" на "+" в приведенном выше примере, чтобы заставить их вести себя как StringTokenizer.
источник
String.split () работает очень хорошо, но имеет свои границы, например, если вы хотите разбить строку, как показано ниже на основе символа одинарной или двойной трубы (|), она не работает. В этой ситуации вы можете использовать StringTokenizer.
ABC | IJK
источник