我有一个包含Movie对象的ArrayList,它是使用此方法从包含File对象的List中产生的:

// returns a list containing movie objects with correct names
private static ArrayList<Movie> createMovieObjs(Collection<File> videoFiles) {
    ArrayList<Movie> movieArrayList = new ArrayList<>();
    Matcher matcher;

    for (File file : videoFiles) {
        matcher = Movie.NAME_PATTERN.matcher(file.getName());
        while (matcher.find()) {
            String movieName = matcher.group(1).replaceAll("\\.", " ");
            Movie movie = new Movie(movieName);

            if (!movieArrayList.contains(movie)) {
                movieArrayList.add(movie);
            }
        }
    }
    return movieArrayList;

}


在上面的代码中,一切正常,获取正确的ArrayList。

然后,我想解析此ArrayList中每个Movie对象的信息,并将该信息设置为该Movie对象:

     // want to parse genre, release year and imdbrating for every Movie object
    for (Movie movie : movieArrayList) {
        try {
            movie.imdbParser();
        } catch (IOException e) {
            System.out.println("Parsing failed: " + e);
        }
    }


这是使用Movie.createXmlLink的Movie.imdbParser(createXmlLink本身可以很好地工作,因此,imbParser-都进行了测试):

private String createXmlLink() {
    StringBuilder sb = new StringBuilder(XML_PART_ONE);
    // need to replace spaces in movie names to "+" - api works that way
    String namePassedToXml = this.title.replaceAll(" ", "+");
    sb.append(namePassedToXml);
    sb.append(XML_PART_TWO);
    return sb.toString();
}

// parses IMDB page and sets releaseDate, genre and imdbRating in Movie objects
public void imdbParser() throws IOException {
    String xmlLink = createXmlLink();

    // using "new Url..." because my xml is on the web, not on my disk
    Document doc = Jsoup.parse(new URL(xmlLink).openStream(), "UTF-8", "", Parser.xmlParser());
    Element movieFromXml = doc.select("movie").first();

    // using array to extract only last genre name - usually the most substantive one
    String[] genreArray = movieFromXml.attr("genre").split(", ");
    this.genre = genreArray[genreArray.length - 1];

    this.imdbRating = Float.parseFloat(movieFromXml.attr("imdbRating"));

    // using array to extract only year of release
    String[] dateArray = movieFromXml.attr("released").split(" ");
    this.releaseYear = Integer.parseInt(dateArray[2]);

}


问题似乎在于访问Movie对象,它不能创建良好的XMLLink,因此当它尝试访问XML类型时,会抛出NPE。
我的错误:

Exception in thread "main" java.lang.NullPointerException
at com.michal.Movie.imdbParser(Movie.java:79)
at com.michal.Main.main(Main.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)


Movie.java:79是:

String[] genreArray = movieFromXml.attr("genre").split(", ");


Main.java:52是:

             movie.imdbParser();

最佳答案

诸如此类的许多错误是由于数据不符合您的预期所致。通常,当处理大量数据时,有时可能只是一条“不符合”的记录!

您说这条线给您带来麻烦;

String[] genreArray = movieFromXml.attr("genre").split(", ");


因此,请分拆线路并调试您的应用程序以查找问题。如果无法调试,则将结果导出到日志文件。


检查movieFromXml是否为NULL。
检查movieFromXml是否包含您期望的“类型”属性
检查属性中的数据是否可以按预期拆分,并产生有效的输出。


通常,在此调用之前查看正在检索的数据是很好的。我经常发现将数据转储到文件中,然后将其加载到外部查看器中以检查它是否符合我的期望,这很有用。

关于java - 将变量设置为ArrayList中的对象时发生NullPointerException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41716486/

10-10 10:57
查看更多