Почему StringTokenizer устарел?

В документации по Java, похоже, ничего не говорится об устаревании StringTokenizer, но я все время слышу о том, что он давно устарел. Был ли он устарел, потому что в нем были ошибки/баги, или String.split() просто лучше использовать в целом?

У меня есть код, который использует StringTokenizer, и мне интересно, стоит ли мне серьезно беспокоиться о его рефакторинге для использования String.split(), или устаревание является чисто вопросом удобства, а мой код безопасен.


person donnyton    schedule 08.08.2011    source источник
comment
StringTokenizer — это устаревший класс (т. е. есть лучшая замена), но он не устарел. Устаревание происходит только тогда, когда класс/метод имеет несколько серьезных недостатков. Похожая ситуация и с Vector: вы почти всегда можете заменить его на ArrayList, но это не плохо и не сломано, поэтому не считается устаревшим.   -  person Joachim Sauer    schedule 08.08.2011
comment
@Joachim, если бы комментарии можно было принять, я бы   -  person donnyton    schedule 09.08.2011
comment
У StringTokenizer есть серьезная проблема со здравым смыслом: он рассматривает последовательные разделители как один разделитель. Это не общепринятый или традиционный смысл. Например, в csv 'a,,b' означает 3 поля, 2-е поле пусто. Но в Stringtokenizer он по умолчанию видит это только как 2 поля, ',' рассматривается как ','. Это уже сбивает с толку многих программистов и заставляет их тратить ненужные усилия на отладку. *** ПРОСТО НЕ ИСПОЛЬЗУЙТЕ ЭТО БОЛЬШЕ ***   -  person Scott Chu    schedule 21.09.2016
comment
@ Скотт Чу: Согласен, это не так скрупулезно, как другие методы. Однако если вы создаете новую ST, включающую разделители в значения токенов, вы можете вернуть пустые значения, в некотором смысле проверяя, содержит ли каждый токен просто один разделитель в качестве своего значения. Конечно, программист должен отрезать последний символ каждой лексемы, потому что это будет разделитель... если только это не последняя лексема в коллекции лексем... тьфу, какая боль. Так что я согласен, используя diff. подход, когда вы хотите подсчитать пустые значения токена как возвращаемые значения, является лучшей идеей, чем использование ST.   -  person Matt Campbell    schedule 20.10.2016
comment
Да, мне кажется, когда StringTokenizer начал отходить на второй план по сравнению с split(), JDK должен был включить какую-то версию split, которая ведет себя как split(), которая существует сейчас, но не включает накладные расходы или сложности регулярного выражения.   -  person Chuck    schedule 26.03.2017
comment
При анализе значения конфигурации, содержащего список, разделенный запятыми, может быть желательно пропустить последовательные разделители: Collections.list(new StringTokenizer(",X, ,,Y , Z,", ", ")) дает [X, Y, Z]   -  person Eron Wright    schedule 17.05.2017


Ответы (8)


Из javadoc для StringTokenizer:

StringTokenizer — это устаревший класс, который сохраняется по соображениям совместимости, хотя его использование в новом коде не рекомендуется. Всем, кто ищет эту функциональность, рекомендуется вместо этого использовать метод split String или пакет java.util.regex.

Если вы посмотрите на String.split() и сравните его с StringTokenizer, существенная разница в том, что String.split() использует регулярное выражение, тогда как StringTokenizer просто использует дословные разделенные символы. Поэтому, если я хочу разбить строку с более сложной логикой, чем отдельные символы (например, разделить на \r\n), я не могу использовать StringTokenizer, но могу использовать String.split().

person Jason S    schedule 08.08.2011

  1. Токенизатор строк Java 10 — не устарел
  2. Токенизатор строк Java 9 — не устарел
  3. Java 8 String Tokenizer — не устарел
  4. Токенизатор строк Java 7 — не устарел
  5. Java 6 String Tokenizer — не устарел
  6. Токенизатор строк Java 5 — не устарел

Если он не помечен как устаревший, он не исчезнет.

person nicholas.hauschild    schedule 08.08.2011
comment
StringTokenizer — это устаревший класс, который сохраняется из соображений совместимости, хотя его использование в новом коде не рекомендуется. Всем, кто ищет эту функциональность, рекомендуется вместо этого использовать метод split String или пакет java.util.regex. - person Miuler; 10.08.2012
comment
Наследие отличается от устаревшего. - person StackOverflowed; 17.08.2012
comment
Лично для меня код с использованием StringTokenizer выглядит проще и чище. - person Audrius Meskauskas; 13.01.2013
comment
Да, я с @h22, часто код StringTokenizer более элегантный/читабельный, чем использование разделения. Я сохраняю разделение, когда мне действительно нужно новое поведение. - person Brian Knoblauch; 20.12.2016

На самом деле StringTokenizer не устарел StringTokenizer в 4 раза быстрее, чем String.split(), и в конкурентном программировании он используется многими разработчиками.

Источник: - Быстрый ввод для Java

person Nishant Thapliyal    schedule 31.07.2015
comment
Это все еще в силе? - person RBz; 05.06.2017
comment
согласно другим ответам да, просто разделение более гибкое, поскольку вы можете использовать регулярные выражения - person David 天宇 Wong; 03.08.2017

Есть проблема с StringTokenize...

Split должен использовать регулярное выражение, StringTokenizer использует String или CharSequence,

но

"a.b..".split(".") вернется {"a","b",""}

и StringTokenizer из "ab.." ... вернет только {"a","b"}

А это очень сложно!!! Будь осторожен!!!

Лучшие и более безопасные альтернативы StringTokenizer:

Гораздо лучше StrongTokenizer в org.apache.common.lang3 ... у него гораздо больше гибкости или

com.google.common.base.Splitter

person cruiserupce    schedule 09.07.2014
comment
Точно. И эта проблема потребовала от наших программистов огромных усилий, чтобы найти ошибку «эффекта бабочки». Почему команда Java поначалу изобретает такие ужасные вещи?... Эх! - person Scott Chu; 21.09.2016

Я не думаю, что причиной этого является метод String.split, потому что split - это медленный способ разбора строки - он компилирует шаблон внутри.

StringTokenizer просто можно заменить более функциональными классами, такими как java.util.Scanner, или вы можете использовать сопоставление шаблонов для получения групп по регулярному выражению.

person Andrey Krot    schedule 08.08.2011

  1. StringTokenizer не устарел

  2. Это немного другая функция и выход ...

Например, если у вас есть "aaa.aa.aa" и вы хотите разделить его на части "aaa", "aa" и "a", вы можете просто написать:

new StringTokenizer("aaa.aa.aa", ".")

Если вы просто используете:

"aaa.aa.aa".split(".")

Он возвращает пустой массив, поскольку он соответствует регулярным выражениям, где . – пробел. Итак, вы должны избежать этого:

"aaa.aa.aa".split("\\.")

Итак, в основном.. split позволяет вам использовать регулярное выражение... это может быть очень полезно

Но StringTokenizer разбирает текст по токенам... а токен может быть даже специальным символом

person cruiserupce    schedule 10.06.2014

StringTokenizer — это устаревший класс, который сохраняется из соображений совместимости, хотя его использование в новом коде не рекомендуется. Всем, кто ищет эту функциональность, рекомендуется вместо этого использовать метод split String или пакет java.util.regex.

В следующем примере показано, как можно использовать метод String.split() для разбиения строки на ее основные токены:

 String[] result = "this is a test".split("\\s");
person MSA    schedule 18.12.2017

Лично я считаю, что StringTokenizer устарел, потому что это был просто сложный способ сделать что-то довольно простое. StringTokenizer, как следует из названия, применяется только к строкам, так почему бы просто не сделать его методом в String. Кроме того, StringTokenizer не поддерживает RegularExpression, не поддерживает регулярное выражение, которое стало чрезвычайно распространенным в конце 90-х и начале 00-х годов, что делает его практически бесполезным.

person Ali    schedule 08.08.2011
comment
Вы правы, это не так, просто рекомендуется не использовать его. Разница в том, что нет гарантии, что устаревшие классы будут по-прежнему предоставляться в будущих выпусках. - person Ali; 08.08.2011
comment
Это тоже не правильно. Существует абсолютная гарантия обратной бинарной совместимости. - person user207421; 09.08.2011