【问题标题】:Java: how to reverse the order of every N elements in an ArrayListJava:如何反转ArrayList中每N个元素的顺序
【发布时间】:2016-04-30 11:48:21
【问题描述】:

我有一个包含数千行单词的输入文本文件,我想在其中写入输出文件,并在其中颠倒每 10 行的顺序。我遍历了整个文本文件,并将其存储在ArrayList<String> array 中,我现在正试图弄清楚如何反转整个 ArrayList 中每 10 行的顺序。

例如输出应该是这样的: Line : 10, 9, 8, 7 ...... 1, 20, 19, 18, 17.....11, 30, 29, 28, 27..​​...21 依此类推,直到我为整个文本文件(存储在 ArrayList 中)完成此操作。以下是我一直用来尝试反转所述行的代码部分。

   for(int i = array.size()-1; i >= array.size()-10; i--){ 
     array.add(array.get(i));
   }

   for (String text : array) {
            w.println(text);
        }

 }

到目前为止,我只读取和反转输入文件的最后 10 行并将其写入输出文件。我一直在想办法在整个数据集中迭代地实现这种模式,以确保我不会遇到索引越界错误。

【问题讨论】:

    标签: java arraylist iteration reverse readfile


    【解决方案1】:

    使用简单的流式传输方法。这基本上是当前的解决方案十行应用一次,而不是最后一次。

    1. 读入十行。
    2. 颠倒这些行1.
    3. 写出十个颠倒的行。
    4. 重复直到处理完整个文件。

    当文件不是 10 行的倍数时,唯一的边缘情况是在最后做一些适当的事情。

    同样的流方法可以用来创建一个new each-10 反向列表。只有在尝试改变原始列表时,它才会“变得复杂”。


    1 步骤 2 和 3 可以通过在写入输出时向后迭代十行列表来组合。

    【讨论】:

    • 好的,此时我的代码正在读取整个输入文件,然后将其存储在 ArrayList 中,然后我正在尝试使用它。您是否建议我改为阅读代码段(一次 10 行),所以阅读前 10 行,反转并添加它们,然后阅读接下来的 10 行,依此类推?我之前尝试过这样做,但是我没有太多阅读文本文件的经验,所以我不知道如何实现它。我怎样才能一次只读取指定行的一部分而不是一次读取整个输入文件?
    • @MastRofDsastR 是的;这就是我建议的方法。最初使用循环读取文件时,只需检查已将多少行添加到列表中:例如。 while (lines.length() < 10 && (line = inp.readLine()) != null) { lines.add(line); }。当读取 10 行时处理输出,然后清除读取的行的 ArrayList(或创建一个新列表)。循环结束后,lines 将包含 最多 10 行。如果少于 10 行,则到达文件末尾。
    • (所以继续运行循环,处理行,如果读取了 10 行,则再次循环整个 read..process 代码。)
    【解决方案2】:

    两种方法:

    1. 如果它已经在内存中,在 ArrayList 中,只需更新该列表。
    2. 如果内存中没有,一次处理 10 行。
      这允许处理无限大的数据而不会耗尽内存。

    选项 1。

    List<String> list = new ArrayList<>();
    // code filling list
    
    for (int i = 0; i < list.size(); i += 10) {
        int endOfBlock = Math.min(i + 10, list.size());
        for (int j = i, k = endOfBlock - 1; j < k; j++, k--) {
            String temp = list.get(j);
            list.set(j, list.get(k));
            list.set(k, temp);
        }
    }
    

    选项 2。

    try (BufferedReader in = new BufferedReader(new FileReader(inFile)),
         PrintWriter out = new PrintWriter(new FileWriter(outFile))) {
        String[] buf = new String[10];
        int len = 0;
        for (String line; (line = in.readLine()) != null; ) {
            buf[len++] = line;
            if (len == 10) {
                while (len > 0)
                    out.println(buf[--len]);
            }
        }
        while (len > 0)
            out.println(buf[--len]);
    }
    

    【讨论】:

      【解决方案3】:

      试试这个

          for (int i = 0, size = array.size(); i < size; i += 10)
              for (int from = i, to = Math.min(i + 10, size); from < to;)
                  Collections.swap(array, from++, --to);
      

      【讨论】:

        【解决方案4】:

        使用辅助计数器变量和 if 语句来检查边界,例如:

        while(counter<array.size()+10)
            int counter = 9; //since index 9 is the 10th line
            for(int i=counter; i>counter-10; i--){
                if(i<array.size()){
                    array.add(array.get(i));
                }
            }
            counter+=10;
        }
        for (String text : array){
                w.println(text);
        }
        

        我唯一担心的是,您似乎只是继续添加到现有数组而不是重新排序或将元素添加到新数组?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-02
          • 2013-02-05
          • 2010-12-13
          • 2023-03-16
          • 2016-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多