You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Scanner读取文件统计行数 实现相邻行翻转输出问题求解

功能需求

扫描输入文件,将文件内容输出到控制台,输出时每一对相邻行的顺序反转;若文件总行数为奇数,则最后一行保持原有顺序不做修改。

原实现思路

最初的实现逻辑为:首先通过while (input.hasNextLine())循环统计文件的总行数,之后初始化长度等于总行数的String数组arrayLines,再通过第二个while循环逐行读取文件内容存入数组,后续遍历数组完成相邻行交换后输出结果。

问题说明

使用两次while (input.hasNextLine())逻辑时存在三个核心问题:

  • 第一次统计行数的循环没有调用nextLine()消费内容,Scanner游标不会向前移动,会直接进入死循环,count值会无限累加
  • 就算第一次循环正常读完所有内容,Scanner读取游标会停在文件末尾,没有重置输入源的情况下,第二次循环无法读取到任何行内容
  • 如果仅使用单次while (input.hasNextLine())遍历,无法提前确定总行数,不能直接初始化定长数组存储内容

原问题附带有缺陷的实现代码如下:

public static void flipLines(Scanner input) {
    int count = 0;
    
    while (input.hasNextLine()) {
        count++;
    }

    String[] arrayLines = new String[count];;
    while (input.hasNextLine()) {
        for (int i = 0; i < count; i++) {
        arrayLines[i] = input.nextLine();
        }
    }

    if (count % 2 == 0) {
        for (int i = 0; i < count; i = i + 2) {
            String temp = arrayLines[i];
            arrayLines[i] = arrayLines[i + 1];
            arrayLines[i + 1] = temp;
        }
    }
    else {
        for (int i = 0; i < count - 1; i = i + 2) {
            String temp = arrayLines[i];
            arrayLines[i] = arrayLines[i + 1];
            arrayLines[i + 1] = temp;
        }
    }
    System.out.println();

    for (int i = 0; i < arrayLines.length; i++) {
        System.out.println(arrayLines[i]);
    }
    input.close();
}
可行解决方案

不需要绕两次读取文件的弯,也不用提前统计总行数,直接用支持动态扩容的ArrayList<String>存储读取到的行即可,单次遍历就能完成所有行的读取。后续做相邻行反转时也不需要单独判断总行数奇偶,把循环步长设为2、终止条件设为遍历到倒数第二行即可——如果总行数是奇数,最后一行不会进入交换逻辑,自然保持原有位置。

修正后的实现代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class LineFlipper {
    public static void flipLines(Scanner input) {
        List<String> lines = new ArrayList<>();
        // 单次遍历读取所有行,动态扩容不需要提前定长度
        while (input.hasNextLine()) {
            lines.add(input.nextLine());
        }
        input.close();

        // 两两交换相邻行,步长为2
        for (int i = 0; i < lines.size() - 1; i += 2) {
            String temp = lines.get(i);
            lines.set(i, lines.get(i + 1));
            lines.set(i + 1, temp);
        }

        // 逐行输出结果
        for (String line : lines) {
            System.out.println(line);
        }
    }
}

注:如果坚持要用定长数组实现,也可以在第一次读取时把所有内容先存在ArrayList里,读完之后调用toArray(new String[0])转成数组即可,本质和上面的逻辑没有区别,没必要做两次文件读取的冗余操作。


内容的提问来源于stack exchange,提问作者Agrim Chhibber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:15:44