1. Обзор
В этой быстрой статье мы рассмотрим фундаментальный класс в Java — StringTokenizer
.
2. Строковый токенизатор
Класс StringTokenizer
помогает нам разделить строки
на несколько токенов.
StreamTokenizer
предоставляет аналогичные функции, но метод токенизации намного проще, чем тот, который используется классом StreamTokenizer .
Методы StringTokenizer
не различают идентификаторы, числа и строки в кавычках, а также не распознают и не пропускают комментарии.
Набор разделителей (символов, разделяющих токены) может быть указан либо во время создания, либо отдельно для каждого токена.
3. Использование StringTokenizer
Простейшим примером использования StringTokenizer
будет разделение строки
на основе указанных разделителей.
В этом быстром примере мы разделим аргумент String и добавим токены в список :
**
**
public List<String> getTokens(String str) {
List<String> tokens = new ArrayList<>();
StringTokenizer tokenizer = new StringTokenizer(str, ",");
while (tokenizer.hasMoreElements()) {
tokens.add(tokenizer.nextToken());
}
return tokens;
}
Обратите внимание, как мы разбиваем строку
на список токенов на основе разделителя ' ,
'. Затем в цикле, используя метод tokens.add()
; мы добавляем каждый токен в ArrayList.
Например, если пользователь вводит « Добро пожаловать, на, foreach.com
», этот метод должен вернуть список, содержащий фрагмент из трех слов, как « Добро пожаловать
», « на
» и « foreach.com
».
3.1. Подход Java 8
Поскольку StringTokenizer
реализует интерфейс Enumeration<Object>
, мы можем использовать его с интерфейсом Collections
Java
. ``
Если мы рассмотрим предыдущий пример, мы можем получить тот же набор токенов, используя метод Collections.list() и
Stream
API:
public List<String> getTokensWithCollection(String str) {
return Collections.list(new StringTokenizer(str, ",")).stream()
.map(token -> (String) token)
.collect(Collectors.toList());
}
Здесь мы передаем сам StringTokenizer
в качестве параметра метода Collections.list() .
Здесь следует отметить, что, поскольку Enumeration
является типом объекта
, нам нужно привести токены к типу String
(т.е. зависит от реализации; если мы используем List
of Integer/Float
, нам нужно будет привести тип с целым/плавающим числом
).
3.2. Варианты StringTokenizer
StringTokenizer
поставляется с двумя перегруженными конструкторами помимо конструктора по умолчанию: StringTokenizer(String str)
и StringTokenizer(String str, String delim, boolean returnDelims):
StringTokenizer(String str, String delim, boolean returnDelims)
принимает дополнительный логический
ввод. Если логическое
значение равно true
, то StringTokenizer
считает сам разделитель токеном и добавляет его в свой внутренний пул токенов.
StringTokenizer(String
str) — это сокращение для предыдущего примера; он внутренне вызывает другой конструктор с жестко заданным разделителем как «\t\n\r\f»
и логическим значением как false.
3.3. Настройка токена
StringTokenizer
также поставляется с перегруженным методом nextToken()
, который принимает на вход фрагмент строки. Этот фрагмент строки
действует как дополнительный набор разделителей; на основе которых токены снова реорганизуются.
Например, если мы можем передать ' e
' в методе nextToken()
для дальнейшего разбиения строки на основе разделителя ' e
':
tokens.add(tokenizer.nextToken("e"));
Следовательно, для данной строки « Hello,foreach.com
» мы создадим следующие токены:
H
llo
ba
ldung.com
3.4. Длина токена
Чтобы подсчитать доступное количество токенов, мы можем использовать метод размера
StringTokenizer
: ``
int tokenLength = tokens.size();
3.5. Чтение из файла CSV
Теперь давайте попробуем использовать StringTokenizer
в реальном случае.
Существуют сценарии, в которых мы пытаемся прочитать данные из CSV-файлов и проанализировать данные на основе заданного пользователем разделителя.
Используя StringTokenizer
, мы можем легко добраться туда:
public List<String> getTokensFromFile( String path , String delim ) {
List<String> tokens = new ArrayList<>();
String currLine = "";
StringTokenizer tokenizer;
try (BufferedReader br = new BufferedReader(
new InputStreamReader(Application.class.getResourceAsStream(
"/" + path )))) {
while (( currLine = br.readLine()) != null ) {
tokenizer = new StringTokenizer( currLine , delim );
while (tokenizer.hasMoreElements()) {
tokens.add(tokenizer.nextToken());
}
}
} catch (IOException e) {
e.printStackTrace();
}
return tokens;
}
Здесь функция принимает два аргумента; один как имя файла CSV (т.е. считывается из папки ресурсов [src -> main -> resources]
), а другой как разделитель.
На основе этих двух аргументов данные CSV считываются построчно, и каждая строка токенизируется с помощью StringTokenizer
.
Например, мы поместили в CSV следующее содержимое:
1|IND|India
2|MY|Malaysia
3|AU|Australia
Следовательно, должны быть сгенерированы следующие токены:
1
IND
India
2
MY
Malaysia
3
AU
Australia
3.6. Тестирование
Теперь давайте создадим быстрый тестовый пример:
public class TokenizerTest {
private MyTokenizer myTokenizer = new MyTokenizer();
private List<String> expectedTokensForString = Arrays.asList(
"Welcome" , "to" , "foreach.com" );
private List<String> expectedTokensForFile = Arrays.asList(
"1" , "IND" , "India" ,
"2" , "MY" , "Malaysia" ,
"3", "AU" , "Australia" );
@Test
public void givenString_thenGetListOfString() {
String str = "Welcome,to,foreach.com";
List<String> actualTokens = myTokenizer.getTokens( str );
assertEquals( expectedTokensForString, actualTokens );
}
@Test
public void givenFile_thenGetListOfString() {
List<String> actualTokens = myTokenizer.getTokensFromFile(
"data.csv", "|" );
assertEquals( expectedTokensForFile , actualTokens );
}
}
4. Вывод
В этом кратком руководстве мы рассмотрели несколько практических примеров использования основного Java StringTokenizer
.
Как всегда, полный исходный код доступен на GitHub .