【问题标题】:JSON API Parsing IssueJSON API 解析问题
【发布时间】:2019-01-30 08:57:33
【问题描述】:

我创建了一个 GUI,其中列出了 Hydra 电影数据库 API 中列出的评分最高和最低的电影。当我使用 Compare.Comparing 和 parseInt 解析它以查找最大和最小 IMDB 评级时,我得到一个数字格式异常。我将最大值更改为 parseDouble 只是为了看看这是否有帮助,我得到了一个空指针异常。

我将提供特别相关的代码和错误,但如果您想要更好的完整图片,这里是 GitHub 上项目的链接: https://github.com/scohen40/cohen-mcw152-MovieDatabaseJSON/tree/bugFixing/src/movieDatabaseApp/movie

这是我的控制器的代码:

package movieDatabaseApp.movie;

import java.awt.event.ActionEvent;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import javax.swing.text.JTextComponent;

import com.google.inject.Inject;

public class MovieController {


    private MovieView view;
    private MovieService service;

    @Inject
    public
    MovieController(MovieView view, MovieService service) {
        this.view = view;
        this.service = service;
    }

    public void refreshData() {
        requestHighest2018();
        requestLowest2018();
    }

    public void requestHighest2018() {
        requestHighestMovies(service.getAllMovies(),
//      requestHighestMovies(service.getMovies2018(),
                view.gethTitleField(),
                view.gethYearField(),
                view.gethRatingField(),
                view.gethLanguageField());          
    }
    void requestLowest2018() {
        requestLowestMovies(service.getAllMovies(),
//      requestLowestMovies(service.getMovies2018(),
                view.getlTitleField(),
                view.getlYearField(),
                view.getlRatingField(),
                view.getlLanguageField());          
    }




    private void requestHighestMovies(Call<List<Movie>> call,
        JTextComponent title,
        JTextComponent year,
        JTextComponent rating,
        JTextComponent language) 
    {
        call.enqueue(new Callback<List<Movie>>() {
            @Override
            public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
                List<Movie> list = response.body();

                showHighest(list, title, year, rating, language);

            }

            @Override
            public void onFailure(Call<List<Movie>> arg0, Throwable t) {
                t.printStackTrace();
            }

        });

    }

    private void requestLowestMovies(Call<List<Movie>> call,
            JTextComponent title,
            JTextComponent year,
            JTextComponent rating,
            JTextComponent language) 
        {
            call.enqueue(new Callback<List<Movie>>() {
                @Override
                public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
                    List<Movie> list = response.body();

                    showLowest(list, title, year, rating, language);

                }

                @Override
                public void onFailure(Call<List<Movie>> arg0, Throwable t) {
                    t.printStackTrace();
                }

            });

        }

    public void showHighest(List<Movie> list,
            JTextComponent title,
            JTextComponent year,
            JTextComponent rating,
            JTextComponent language) 
    {
        Optional<Movie> highest = list.stream()
                .max(Comparator.comparingDouble(e -> Double.parseDouble(e.getImdb_rating())));

        title.setText(String.valueOf(highest.get().getTitle()));
        year.setText(String.valueOf(highest.get().getMovie_year()));
        rating.setText(String.valueOf(highest.get().getImdb_rating()));
        language.setText(String.valueOf(highest.get().getLanguage()));
    }

    void showLowest(List<Movie> list,
            JTextComponent title,
            JTextComponent year,
            JTextComponent rating,
            JTextComponent language) 
    {
        Optional<Movie> lowest = list.stream()
                .min(Comparator.comparing(e -> Integer.parseInt(e.getImdb_rating())));

        title.setText(String.valueOf(lowest.get().getTitle()));
        year.setText(String.valueOf(lowest.get().getMovie_year()));
        rating.setText(String.valueOf(lowest.get().getImdb_rating()));
        language.setText(String.valueOf(lowest.get().getMovie_year()));
    }

}

这是我得到的最大 parinsing 为 double 和 min 为 int 的错误:

java.lang.NullPointerException

at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1838)

at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)

at java.lang.Double.parseDouble(Double.java:538)

at movieDatabaseApp.movie.MovieController.lambda$0(MovieController.java:109)

at java.util.Comparator.lambda$comparingDouble$8dcf42ea$1(Comparator.java:532)

at java.util.function.BinaryOperator.lambda$maxBy$1(BinaryOperator.java:74)

at java.util.stream.ReduceOps$2ReducingSink.accept(ReduceOps.java:123)

at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)

at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)

at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)

at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)

at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)

at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)

at java.util.stream.ReferencePipeline.max(ReferencePipeline.java:515)

at movieDatabaseApp.movie.MovieController.showHighest(MovieController.java:109)

at movieDatabaseApp.movie.MovieController$1.onResponse(MovieController.java:65)

at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:123)

at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)

at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

at java.lang.Thread.run(Thread.java:748)

java.lang.NumberFormatException:对于输入字符串:“7.4”

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

at java.lang.Integer.parseInt(Integer.java:580)

at java.lang.Integer.parseInt(Integer.java:615)

at movieDatabaseApp.movie.MovieController.lambda$1(MovieController.java:124)

at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469)

at java.util.function.BinaryOperator.lambda$minBy$0(BinaryOperator.java:59)

at java.util.stream.ReduceOps$2ReducingSink.accept(ReduceOps.java:123)

at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)

at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)

at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)

at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)

at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)

at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)

at java.util.stream.ReferencePipeline.min(ReferencePipeline.java:520)

at movieDatabaseApp.movie.MovieController.showLowest(MovieController.java:124)

at movieDatabaseApp.movie.MovieController$2.onResponse(MovieController.java:89)

at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:123)

at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)

at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

at java.lang.Thread.run(Thread.java:748)

我对 JSON API 集成还很陌生,所以我真的不知道该主题的错误是什么意思,也不知道什么是正常的。任何帮助将不胜感激。

另外 - 如果您想查看,这里是正在解析的原始 JSON:https://hydramovies.com/api-v2/?source=http://hydramovies.com/api-v2/current-Movie-Data.csv

【问题讨论】:

    标签: java json api retrofit jsonparser


    【解决方案1】:

    我认为这个错误与 JSON 本身没有任何关系。您获得 NPE 或 NFE 是因为您的列表中的一部或多部电影没有 IMDB 评级,或者评级中有小数,无法进行整数解析,

    【讨论】:

    • 所以我实际上认为这可能是问题所在,所以我尝试将评级切换到运行时,但我仍然遇到同样的问题:/ 我得到了 NPE
    • 在一个地方,您有 Integer.parseInt 由于“7.4”被传递而失败。在其他地方,您有 Double.parseDouble 由于传递了 null 而失败。尝试在两个地方都使用 Double.parseDouble 并明确处理 NULL。可能是这样——list.stream().filter(a-> a !=null).max(........
    • java.lang.Double 处 sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1838) 处的 java.lang.NullPointerException。 parseDouble(Double.java:538) at movieDatabaseApp.movi​​e.MovieController.lambda$1(MovieController.java:109) at java.util.Comparator.lambda$comparingDouble$8dcf42ea$1(Comparator.java:532) at java.util.function .BinaryOperator.lambda$maxBy$1(BinaryOperator.java:74) at java.util.stream.ReduceOps$2ReducingSink.accept(ReduceOps.java:123) at
    • 我确定您有一个 hte 电影实例指向 NULL 或 getImdb_String 返回 NULL。使用传统的 FOR 循环并打印所有 IMDB 评级:) - docs.oracle.com/javase/7/docs/api/java/lang/…
    • 我确定可能有,但如果我按照您的建议将它们过滤掉,为什么我仍然会遇到异常?我只是做得不对吗?可选 最高 = list.stream().filter(e -> e!=null) .max(Comparator.comparingDouble(e -> Double.parseDouble(e.getImdb_rating())));
    【解决方案2】:

    更新:我最终将 imdb_ratings 的数据类型从 String 切换为 Double 并取出过滤器和解析器。 现在可以了!

    您可以在上面列出的我的 GitHub 上查看它。

    【讨论】:

      猜你喜欢
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多