Java — Как я могу выполнить метод чтения, не пропуская строку из-за другого метода readline

#java #java.util.scanner #bufferedreader

#java #java.util.scanner #bufferedreader

Вопрос:

Я пытаюсь настроить систему рекордов для сортировки результатов из файла и отделения имен от чисел. Но когда я пытаюсь использовать readline дважды, он пропускает 1 строку из-за другого метода readline. Кто-нибудь может мне помочь, пожалуйста, это для школы!

Пример файла:

кевин: 50 Дастин: 31 никто: 71 imax: 23

Вот код:

 public class Main {
public static void main(String[] args) {
    ArrayList<Integer> result = new ArrayList<>();
    String name="";
    try (BufferedReader br= new BufferedReader(new FileReader("res/highscore.txt"))){
        while (br.ready()){
            result.add(Integer.parseInt(br.readLine().split(":")[1]));
            name = br.readLine().split(";")[0];
            System.out.println(name);
        }
        Collections.sort(result);
        Collections.reverse(result);
        for (Integer integer : result) {
            System.out.println(integer);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  

}

Комментарии:

1. Не могли бы вы предоставить образец данных для визуализации проблемы?

2. Если вы хотите получить два элемента данных из одной строки, затем сохраните результат readLine в переменной и проанализируйте данные из этой переменной.

3. Включите ваш highscore.txt файл в вопрос, пожалуйста.

4. Ваше использование BufferedReader.ready() здесь недопустимо. Это не тест на конец потока. Вы должны проводить тестирование на readLine() возврат null.

Ответ №1:

Небольшое объяснение ответа @thewho69.

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

Это делает readLine метод неидемпотентным, что означает, что повторный вызов метода с одинаковыми параметрами (в данном случае none) не обязательно вернет один и тот же результат.

Чтобы не попасть в эту ловушку, вы должны найти способ использовать текущую строку несколько раз, вызывая br.readLine() метод только один раз — таким образом, устанавливая положение курсора только один раз за итерацию, что желательно в данном случае. Хорошим решением этой проблемы является то, что @thewho69 предложил ~ 20 минут назад.

Ответ №2:

Просто сохраните каждую строку в переменной:

 public class Main {
    public static void main(String[] args) {
    ArrayList<Integer> result = new ArrayList<>();
    String name="";
    try (BufferedReader br= new BufferedReader(new FileReader("res/highscore.txt"))){
        String line;
        while ((line = br.readLine()) != null){
            result.add(Integer.parseInt(line.split(":")[1]));
            name = line.split(";")[0];
            System.out.println(name);
        }
        Collections.sort(result);
        Collections.reverse(result);
        for (Integer integer : result) {
            System.out.println(integer);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}