Java StringTokenizer - Проблемы с использованием nextToken () с подстрокой - PullRequest
0 голосов
/ 06 августа 2020

У меня есть текстовый файл, который я должен перебирать и хочу переместить определенные элементы каждой строки в ArrayList. Каждая строка файла имеет формат: число. Номер строки. decimal decimal Поскольку два числа имеют точку (.) в конце, и мне нужно читать их как строку, удалил. используя подстроку, а затем преобразовать в примитивный тип данных (int или short).

Пример в файле: 294. ABC123 66. .00 .00

Я получаю диапазон строк ошибка, если я попробую это: (* temp is a String)

while(fileLine.hasMoreTokens())
{
    oneNumber = Integer.valueOf(fileLine.nextToken().substring(0, 
                          fileLine.nextToken().indexOf('.')));
    twoString = fileLine.nextToken();
    threeNumber = Short.valueOf(fileLine.nextToken().substring(0, 
                          fileLine.nextToken().indexOf('.')));
    temp = fileLine.nextToken();    //Handle attributes not required
    temp = fileLine.nextToken();    //Handle attributes not required
}

Я считаю, что это происходит потому, что nextToken () в параметрах подстроки сбивает StringTokenizer с толку. Поэтому я исправил это так:

                while(fileLine.hasMoreTokens())
                {
                    temp = fileLine.nextToken();
                    oneNumber = Integer.valueOf(temp.substring(0, temp.indexOf('.')));
                    twoString = fileLine.nextToken();
                    temp = fileLine.nextToken();
                    threeNumber= Short.valueOf(temp.substring(0, temp.indexOf('.')));
                    temp = fileLine.nextToken();
                    temp = fileLine.nextToken();
                }

Хотя это работает, оно кажется немного избыточным. Могу ли я попытаться сделать этот очиститель, сохранив при этом StringTokenizer?

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Это предполагаемое поведение .nextToken(): он возвращает токен и проходит мимо текущего токена. Когда вы используете Integer.valueOf(fileLine.nextToken().substring(0, fileLine.nextToken().indexOf('.'))), вы дважды вызываете .nextToken(), что означает, что вы имеете дело с двумя разными токенами. Это не имеет ничего общего с тем, как работает String#substring. Вам нужно сохранить токен в переменной, если вам нужно выполнить с ним дополнительные операции. Точно такая же проблема может быть вызвана двойным использованием BufferedReader#readLine, когда нужно сохранить значение.

0 голосов
/ 06 августа 2020

Ага. nextToken() сохраняет состояние, его вызов меняет ситуацию, поэтому использование его дважды в одной строке потребует два токена.

Мне кажется, что ваш второй фрагмент легче читать, поэтому я не уверен, в чем проблема является. Предположительно, вы хотите, чтобы ваш код был более читабельным.

Простое решение - создать вспомогательные методы:

while (fileLine.hasMoreTokens()) {
    oneNumber = fetchHeadingNumber(fileLine);
    twoString = fileLine.nextToken();
    threeNumber = fetchHeadingNumber(fileLine);
    fileLine.nextToken(); // no need to assign it.
    fileLine.nextToken();
}

с помощью этого метода:

int fetchHeadingNumber(StringTokenizer t) {
    String token = t.nextToken();
    return Integer.parseInt(token.substring(0, token.indexOf('.')));
}

вы можете go еще дальше и создайте класс, представляющий строку, в которой есть весь код, необходимый для ее анализа (я придумал имена; ваш фрагмент не дает понять, что представляет собой эта строка):

@lombok.Value class InventoryItem {
    int warehouse;
    String name;
    int shelf;

    public static InventoryItem read(StringTokenizer tokenizer) {
        int warehouse = num(tokenizer);
        String name = tokenizer.nextToken();
        int shelf = num(tokenizer);
        tokenizer.nextToken();
        tokenizer.nextToken();
        return new InventoryItem(warehouse, name, shelf);
    }
    private static int num(StringTokenizer t) {
        String token = t.nextToken();
        return Integer.parseInt(token.substring(0, token.indexOf('.')));
    }
}

, а затем чтение строки и получение, скажем, места, в котором она хранится, намного лучше: теперь у вещей есть имена!

InventoryItem item = InventoryItem.read(fileLine);
System.out.println("This item is in warehouse " + item.getWarehouse());

NB: Использует @ Value lombok чтобы в этом ответе не было слишком много шаблонов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...