Перейти к основному содержимому

Краткое руководство по Java StringTokenizer

· 4 мин. чтения

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 .