【问题标题】:Taking in a File and Alphabetizing it in Java: NullPointer Exception [duplicate]接收文件并在 Java 中按字母顺序排列:NullPointer 异常 [重复]
【发布时间】:2017-01-24 15:28:39
【问题描述】:

我正在尝试读取文件并按字母顺序排列名称。该文件有一个名字和姓氏的列表,例如:

鲍勃花 蒂娜海 脆皮蟹 马克克鲁兹

我想使用冒泡排序来按字母顺序排列字符串。我不断收到错误消息:

java.lang.NullPointerException 在 java.lang.String.compareTo(未知来源) 在 BubbleSort.Alphabetize(BubbleSort.java:48) 在 BubbleSort.main(BubbleSort.java:31)

到目前为止我的代码是:

import java.util.*;
import java.io.*;

public class BubbleSort
{
    public static void main(String[] args)
        throws IOException
    {
        File inData = new File("names.txt");
        if (!inData.exists()) {
            System.out.println("File does not exist");
            System.exit(0);
        }

        Scanner input = new Scanner(inData);
        int x = 0;
        String[] name = new String[30];
        //String[] extra = new String[30];

        while (input.hasNext()) {
            name[x] = input.next();
            input.nextLine();

            // extra[x] = input.next();
            // System.out.println(name[x]);
            x++;
        }

        BubbleSort sorter = new BubbleSort();
        sorter.Alphabetize(name, x);

        for (int i = 0; i < x; i++) {
            System.out.println(name[i]);
        }
        input.close();
    }

    private static void Alphabetize(String[] array, int a)
        throws IOException
    {
        String temp;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j].compareTo(array[j + 1]) > 0) {
                    temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }
}

我不明白如何解决这个错误,或者什么是真正的错误。

【问题讨论】:

  • @Marvin 我看过那个帖子,它确实没有完全了解我的情况,我无法完全理解。
  • BubbleSort.java:48 是哪一行?你在那条线上有一个 NPE。
  • @student100 您可以运行循环直到您传递的 a 变量,这将消除从 array 获取空值的可能性,正如 Anton 在他的回答中所解释的那样。

标签: java arrays file bubble-sort


【解决方案1】:

您正在对一个未使用(因此为空)的数组元素进行排序。在整个排序方法中,您应该使用a 而不是array.length。这就是a 的用途。

【讨论】:

    【解决方案2】:

    我猜String[] name = new String[30]; 包含空元素。在您的示例中,只有 8 个字符串

    Bob Flower
    
    Tina Sea
    
    Krusty Crab
    
    Mark Klutz
    

    但是,您创建了一个包含 30 个元素的数组。结果,数组中将有 8 个String 对象和 22 个null。 稍后在array[j].compareTo(array[j + 1]) 中会比较有效的String 对象和null。尝试使用ArrayList 而不是String[]

    【讨论】:

      【解决方案3】:

      您在分配内存(数组)和使用计算的索引来访问元素时遇到问题。因此,您在访问未初始化的元素时遇到问题,或者在其他时候您可能会得到 IndexOutOfBoundExceptions。作为初学者,学习和做低级可能会有所帮助,但我想分享一点以供您兴趣,也可能有助于不要讨厌Java。

      文件类老了,尝试使用Java 7自带的NIO.2。

      对于更高级别的抽象,这里有一个单行排序解决方案:

      Files.readAllLines(Paths.get("names.txt"))
           .stream().filter(p -> p.length() > 0)
           .forEachOrdered(System.out::println);
      

      甚至可以在 JShell(Java 9) 中试用。

      Files.readAllLines(Paths.get("names.txt"))
           .stream().filter(p -> p.length() > 0)
           .sorted()
           .toArray(String[]::new);
      

      输出:

      { "Bob Flower", "Krusty Crab", "Mark Klutz", "Tina Sea" }
      

      【讨论】:

      • 这其实是不等价的。 OP 的代码从每一行读取第一个标记,而不是整行。
      【解决方案4】:

      不 - 您正在访问一个超出数组长度大小的空数组元素。当你在最后并访问数组[j + 1]时,它是空的。

            if (array[j].compareTo(array[j + 1]) > 0) { <- culprit here
      

      【讨论】:

      • 不,什么? “超过数组长度的大小”是什么意思?
      • 这意味着如果数组中有 4 个元素并且您正在循环遍历它,那么当您到达数组 [3] 时,它就是最后一个元素。如果您检查下一个元素是否有可能交换它,他会检查 array[3 + 1] 并且它不存在。
      • EJP - 当我开始回答时,您的答案并不存在。
      • 酷。我被标记为正确答案
      猜你喜欢
      • 2014-12-21
      • 1970-01-01
      • 2017-12-19
      • 2011-05-29
      • 2020-03-29
      • 1970-01-01
      • 2017-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多