在我的一门编程课程中,我的任务是创建一个读写json到文件的类.

我使用了json.Simple库,但很快意识到几乎所有行都收到了"类型安全警告"?

然后,我try 尽可能多地使用ArrayList和HashMap,因为JSONObject和JSON数组扩展了它们.据我所知,这是一个问题.

我对编程相当陌生,如果能给我一些提示,我会非常感激,当谈到我是如何解决这项任务的时候.

我如何摆脱这些类型的安全警告?

我的代码是:

//imports
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.JSONArray;
import org.json.simple.parser.ParseException;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDate;
import java.util.Collection;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;

public class ReadAndWrite {
    /**
     * This is a class for reading and writing to the userData file stored in the users home directory.
     * The file is stored in json format. The classes are first converted to json format and then written to the file.
     * The classes are then read from the file and converted back to the classes.
     */

    /**
     * For the first version of the application we will only have one user. 
     * This is why we have a dummy name for the user. To parse the classes to json
     * we are using the json-simple library. JSONObjects 
     */
    private static String dummyName = "dummyName";
    private static String fileLocation = System.getProperty("user.home") + System.getProperty("file.separator") + "loftUserData.json";
    private JSONParser parser = new JSONParser();
    private Collection<User> userClasses = new ArrayList<User>();
    private Collection<Workout> workoutsClasses = new ArrayList<Workout>();
    private Collection<Exercise> exercisesClasses = new ArrayList<Exercise>();
    private Collection<Set> setsClasses = new ArrayList<Set>();
    
    
    /**
     * Private method for setting up a set class to json format.
     * @param list of sets
     * @return ArrayList<HashMap<String, Object>> -> sets in json format
     */
    private ArrayList<HashMap<String, Object>> setSetsJsonArray(List<Set> list) {
        ArrayList<HashMap<String, Object>> setsArray = new ArrayList<HashMap<String, Object>>();
        int i = 0;
        for (Set set : list) {
            HashMap<String, Object> setJson = new HashMap<String, Object>();
            setJson.put("setNumber", ++i);
            setJson.put("weight", set.getWeight());
            setJson.put("reps", set.getReps());
            setsArray.add(setJson);
        }
        return setsArray;
    }
    /**
     * Private method for setting up a exercise class to json format.
     * @param list of exercises
     * @return ArrayList<HashMap<String, Object>> -> exercises in json format
     */
    private ArrayList<HashMap<String, Object>> setExercisesJsonArray(List<Exercise> list) {
        ArrayList<HashMap<String, Object>>  exercisesArray = new ArrayList<HashMap<String, Object>>();
        for (Exercise exercise : list) {
            HashMap<String, Object> exerciseJson = new HashMap<String, Object>();
            exerciseJson.put("exerciseName", exercise.getName());
            exerciseJson.put("sets", setSetsJsonArray(exercise.getSets()));
            exercisesArray.add(exerciseJson);
        }
        return exercisesArray;
    }
    /**
     * Private method for setting up a workout class to json format.
     * @param workout
     * @return HashMap<String, Object> -> workout in json format
     */
    private HashMap<String, Object> formatWorkoutClassToJson(Workout workout) {
        HashMap<String, Object> workoutJson = new HashMap<String, Object>();
        workoutJson.put("exercises", setExercisesJsonArray(workout.getExercises()));
        workoutJson.put("date", workout.getDate().toString());
        
        return workoutJson;
    }

    //Writing a workout class to the userData file in json format
    /** 
     * The method to be used for writing a workout class to the userData file in json format.
     * @param workout
     */
    public void writeWorkoutToUser(Workout workout) {
        ArrayList<HashMap<String, Object>> existingData = readDataFromFile();
        ArrayList<HashMap<String, Object>> users = new ArrayList<HashMap<String, Object>>();
        
        HashMap<String, Object> user = new HashMap<String,Object>();
    
        // Setting up user
        if (existingData == null) {
            user.put("name", dummyName);
            user.put("workouts", new ArrayList<HashMap<String, Object>>());
        } else {
            HashMap<String, Object> userDummy = existingData.get(0);
            user = userDummy;
        }
    
        // Adding to user
        HashMap<String, Object> workoutInJSONFormat = this.formatWorkoutClassToJson(workout);
        ArrayList<HashMap<String, Object>> workoutsJsonArray = (ArrayList<HashMap<String, Object>>) user.get("workouts");
        workoutsJsonArray.add(workoutInJSONFormat);
    
        users.add(user);
        JSONArray jsonFormat = new JSONArray();
        jsonFormat.addAll(users);
    
        try (FileWriter file = new FileWriter(fileLocation)) {    
            file.write(jsonFormat.toJSONString()); 
            file.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * Private method for reconstructing the user class from a JSONArray format.
     * @param users JSONArray of users
     * @return ArrayList of users, in our case there is only one user.
     */
    private ArrayList<User> classReconstructor(JSONArray users) {
        for (Object userObject : users) {
            JSONObject user = (JSONObject) userObject;
            String name = (String) user.get("name");
            
            JSONArray workouts = (JSONArray) user.get("workouts");
            for (Object workoutObject : workouts) {
                JSONObject workout = (JSONObject) workoutObject;
                LocalDate date = LocalDate.parse((String) workout.get("date"));

                JSONArray exercises = (JSONArray) workout.get("exercises");
                for (Object exerciseObject : exercises) {
                    JSONObject exercise = (JSONObject) exerciseObject;
                    String exerciseName = (String) exercise.get("exerciseName");

                    JSONArray sets = (JSONArray) exercise.get("sets");
                    for (Object setObject : sets) {
                        JSONObject set = (JSONObject) setObject;
                        int weight = ((Long) set.get("weight")).intValue();
                        int reps = ((Long) set.get("reps")).intValue();

                        Set newSet = new Set(weight, reps);
                        setsClasses.add(newSet);
                    }
                    Exercise newExercise = new Exercise(exerciseName);
                    for (Set set : setsClasses) {
                        newExercise.addSet(set);
                    }
                    exercisesClasses.add(newExercise);
                }
                Workout newWorkout = new Workout(date);
                for (Exercise exercise : exercisesClasses) {
                    newWorkout.addExercise(exercise);
                }
                workoutsClasses.add(newWorkout);
            }
            User newUser = new User(name);
            for (Workout workout : workoutsClasses) {
                newUser.addWorkout(workout);
            }
            userClasses.add(newUser);
        }
        return (ArrayList<User>) userClasses;
    }

    /**
     * Private method for reading data from the file.
     * @return JSONArray of all users. In our case there is only one user.
     */
    private ArrayList<HashMap<String, Object>> readDataFromFile() {
        try (FileReader reader = new FileReader(fileLocation)){
            if (reader.ready()) {
                Object obj = parser.parse(reader);
                JSONArray users = (JSONArray) obj;
                
                ArrayList<HashMap<String, Object>> usersList = (ArrayList<HashMap<String, Object>>) users;

                return usersList;
            } else {
                //The file can be empty this is not an error, it just means that there is no data to read.
            }
        } catch (FileNotFoundException e) {
            // If it is not found, it will be created at a later point, so this is fine
            return null;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e){
            e.printStackTrace();
        }
        return null;
    }

    /** 
     * The method to be used for getting the user class from the file.
     * @return User class
     */
    public User returnUserClassFromFile() {
        ArrayList<HashMap<String, Object>> users = readDataFromFile();
        if (users == null) {
            return new User(dummyName);
        }
        JSONArray usersJson = (JSONArray) users;
        ArrayList<User> user = this.classReconstructor(usersJson);
        User userClass = user.get(0);
        return userClass;
    }

出现问题的位置:

ArrayList<HashMap<String, Object>> workoutsJsonArray = (ArrayList<HashMap<String, Object>>) user.get("workouts");

jsonFormat.addAll(users);

ArrayList<HashMap<String, Object>> usersList = (ArrayList<HashMap<String, Object>>) users;

The warning messages : enter image description here

我try 使用JSON数组和JSONObject的ArrayList和HashMap实例

推荐答案

您遇到的类型安全警告是因为您正在使用100的集合,并试图将它们强制转换为更具体的类型.虽然这种强制转换是可以完成的,但它不是类型安全的,因为您的集合的泛型类型没有显式定义,从而导致未判断的类型转换.

要消除这些类型安全警告,您应该考虑使用允许您直接使用Java对象的JSON库,例如Google的100101.这些库将允许您将JSON数据直接映射到Java类,并避免强制转换问题.

下面是使用gson库重构代码的方法:

  1. 将gson依赖项添加到项目中(如果尚未添加
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10</version> <!-- Use the latest version -->
</dependency>

  1. 重构您的ReadAndWrite类以使用gson:
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class ReadAndWrite {
    private static String dummyName = "dummyName";
    private static String fileLocation = System.getProperty("user.home") + System.getProperty("file.separator") + "loftUserData.json";
    private Gson gson = new Gson();

    // ...

    public void writeWorkoutToUser(Workout workout) {
        List<User> existingData = readDataFromFile();
        List<User> users = new ArrayList<>();

        User user;

        if (existingData == null || existingData.isEmpty()) {
            user = new User(dummyName);
        } else {
            user = existingData.get(0);
        }

        user.addWorkout(workout);
        users.add(user);

        String jsonFormat = gson.toJson(users);

        try (FileWriter file = new FileWriter(fileLocation)) {
            file.write(jsonFormat);
            file.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private List<User> readDataFromFile() {
        try (FileReader reader = new FileReader(fileLocation)) {
            if (reader.ready()) {
                List<User> users = gson.fromJson(reader, new TypeToken<List<User>>() {}.getType());
                return users;
            } else {
                // The file can be empty; this is not an error.
            }
        } catch (FileNotFoundException e) {
            // If it is not found, it will be created at a later point, so this is fine.
            return null;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public User returnUserClassFromFile() {
        List<User> users = readDataFromFile();

        if (users == null || users.isEmpty()) {
            return new User(dummyName);
        }

        return users.get(0);
    }
}

通过这种重构,您不再需要在JSON集合和Java对象之间进行转换,从而使您的代码更安全、更易于维护.

Java相关问答推荐

Maven Google Sheets版本问题

伪类focus-in不适用于PFA中的选项卡

如何使用解析器组合子解析Java数组类型签名?

如何在Javascript中设置文本区域圆角的样式

H2弹簧靴试验跌落台

在AnyLogic中增加变量计数

RxJava PublishSubject缓冲区元素超时

Java FX中的河内之塔游戏-在游戏完全解决之前什么都不会显示

无法在WebSocket onMessage中捕获错误

按属性值从流中筛选出重复项

如何对多个字段进行分组和排序?

Java堆中的许多java.time.ZoneRegion实例.ZoneId实例不应该被缓存吗?

在整数列表中查找和可被第三个整数整除的对时出现无法解释的RunTimeError

Java中的发布/订阅-Long Live和Short Live Publisher,哪种方法是正确的?

Java KeyListener不工作或被添加

在ECLIPSE上的M1 Pro上运行JavaFX的问题

OAuth:登录后无法查看Google邮箱地址

如何在Selenium上继续使用最新的WebDriver版本

Spring Integration SFTP 连接失败 - 无法协商 kex 算法的密钥交换

有没有办法仅将 JComboBox 中的选定项目居中(因此保持组合框中的所有项目左对齐)