You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android解析烘焙JSON并返回多个ArrayList的实现问询

处理多ArrayList返回的最佳实践

首先,先帮你指出代码里一个容易忽略的bug:在解析步骤的循环里,你写的是idSteps = recipeObject.getInt(IDSTEPS);,这里应该用stepsObject.getInt(IDSTEPS),不然所有步骤的id都会变成当前菜谱的id,而不是步骤自己的id,这个得先修正~

回到你的核心问题:实现返回多个ArrayList的功能。其实看你的代码结构,BakingItem已经包含了对应的IngredientsItem列表和StepsItem列表,所以直接返回ArrayList<BakingItem>是最合理的选择,因为每个菜谱对象本身就携带了它自己的食材和步骤,不需要额外用ArraysLists来包裹三个列表(这样反而会造成数据冗余,比如parsedRecipeData里每个元素都重复存储了全局的Baking、Ingredients、Steps)。

如果你确实需要单独返回多个列表(比如某些特殊场景),可以用一个自定义的封装类来承载这些列表,而不是用ArrayList<ArraysLists>这种嵌套方式。下面给你两种方案:

方案一:推荐——直接返回ArrayList<BakingItem>

这种方式最符合面向对象的设计,因为菜谱本身就是一个包含食材和步骤的实体。优化后的OpenBakingJsonUtils代码如下:

public final class OpenBakingJsonUtils {
    public static ArrayList<BakingItem> getSimpleBakingStringsFromJson(Context context, String bakingJsonString) throws JSONException {
        // 定义常量
        final String ID = "id";
        final String NAME = "name";
        final String SERVINGS = "servings";
        final String INGREDIENTS = "ingredients";
        final String STEPS = "steps";
        final String QUANTITY = "quantity";
        final String MEASURE = "measure";
        final String INGREDIENT = "ingredient";
        final String IDSTEPS = "id";
        final String SHORTDESCRIPTION = "shortDescription";
        final String DESCRIPTION = "description";
        final String VIDEOURL = "videoURL";
        final String THUMBNAILURL = "thumbnailURL";

        ArrayList<BakingItem> parsedRecipeData = new ArrayList<>();
        JSONArray recipeArray = new JSONArray(bakingJsonString);

        for (int i = 0; i < recipeArray.length(); i++) {
            JSONObject recipeObject = recipeArray.getJSONObject(i);
            int id = recipeObject.getInt(ID);
            String name = recipeObject.getString(NAME);
            int servings = recipeObject.getInt(SERVINGS);

            // 解析食材列表
            ArrayList<IngredientsItem> ingredients = new ArrayList<>();
            JSONArray ingredientsArray = recipeObject.getJSONArray(INGREDIENTS);
            for(int j = 0 ; j< ingredientsArray.length(); j++) {
                JSONObject ingredientsObject = ingredientsArray.getJSONObject(j);
                double quantity = ingredientsObject.getDouble(QUANTITY);
                String measure = ingredientsObject.getString(MEASURE);
                String ingredient = ingredientsObject.getString(INGREDIENT);
                ingredients.add(new IngredientsItem(quantity, measure, ingredient));
            }

            // 解析步骤列表(修复了idSteps的bug)
            ArrayList<StepsItem> steps = new ArrayList<>();
            JSONArray stepsArray = recipeObject.getJSONArray(STEPS);
            for(int j = 0 ; j< stepsArray.length(); j++) {
                JSONObject stepsObject = stepsArray.getJSONObject(j);
                int idSteps = stepsObject.getInt(IDSTEPS); // 这里改成stepsObject
                String shortDescription = stepsObject.getString(SHORTDESCRIPTION);
                String description = stepsObject.getString(DESCRIPTION);
                String videoURL = stepsObject.getString(VIDEOURL);
                String thumbnailURL = stepsObject.getString(THUMBNAILURL);
                steps.add(new StepsItem(idSteps, shortDescription, description, videoURL, thumbnailURL));
            }

            // 将当前菜谱加入列表
            parsedRecipeData.add(new BakingItem(id, name, servings, ingredients, steps));
        }
        return parsedRecipeData;
    }
}

这样调用的时候,你只需要拿到ArrayList<BakingItem>,然后遍历每个BakingItem,通过它的getIngredients()和getSteps()方法就能获取对应的子列表了(记得给BakingItem添加这两个getter方法)。

方案二:自定义封装类返回多个列表

如果确实需要一次性返回三个独立的列表,可以创建一个专门的封装类:

public class RecipeDataBundle {
    private ArrayList<BakingItem> bakingItems;
    private ArrayList<IngredientsItem> allIngredients;
    private ArrayList<StepsItem> allSteps;

    public RecipeDataBundle(ArrayList<BakingItem> bakingItems, ArrayList<IngredientsItem> allIngredients, ArrayList<StepsItem> allSteps) {
        this.bakingItems = bakingItems;
        this.allIngredients = allIngredients;
        this.allSteps = allSteps;
    }

    // 添加getter方法
    public ArrayList<BakingItem> getBakingItems() { return bakingItems; }
    public ArrayList<IngredientsItem> getAllIngredients() { return allIngredients; }
    public ArrayList<StepsItem> getAllSteps() { return allSteps; }
}

然后修改OpenBakingJsonUtils的返回值:

public static RecipeDataBundle getSimpleBakingStringsFromJson(Context context, String bakingJsonString) throws JSONException {
    // ... 前面的常量定义不变

    ArrayList<BakingItem> bakingItems = new ArrayList<>();
    ArrayList<IngredientsItem> allIngredients = new ArrayList<>();
    ArrayList<StepsItem> allSteps = new ArrayList<>();

    JSONArray recipeArray = new JSONArray(bakingJsonString);
    for (int i = 0; i < recipeArray.length(); i++) {
        // ... 解析菜谱、食材、步骤的逻辑不变

        bakingItems.add(new BakingItem(id, name, servings, ingredients, steps));
        allIngredients.addAll(ingredients); // 将当前菜谱的食材加入全局列表
        allSteps.addAll(steps); // 将当前菜谱的步骤加入全局列表
    }

    return new RecipeDataBundle(bakingItems, allIngredients, allSteps);
}

补充:完成IngredientsItem的Parcelable实现

你的IngredientsItem代码没写完,这里给你补全:

public class IngredientsItem implements Parcelable {
    private double quantity;
    private String measure;
    private String ingredient;

    public IngredientsItem(double quantity, String measure, String ingredient) {
        this.quantity = quantity;
        this.measure = measure;
        this.ingredient = ingredient;
    }

    // Parcelable实现
    private IngredientsItem(Parcel in) {
        quantity = in.readDouble();
        measure = in.readString();
        ingredient = in.readString();
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeDouble(quantity);
        out.writeString(measure);
        out.writeString(ingredient);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Parcelable.Creator<IngredientsItem> CREATOR = new Parcelable.Creator<IngredientsItem>() {
        @Override
        public IngredientsItem createFromParcel(Parcel in) {
            return new IngredientsItem(in);
        }

        @Override
        public IngredientsItem[] newArray(int size) {
            return new IngredientsItem[size];
        }
    };

    // 添加getter方法
    public double getQuantity() { return quantity; }
    public String getMeasure() { return measure; }
    public String getIngredient() { return ingredient; }
}

同样,记得给StepsItem也补全Parcelable的实现哦~


内容的提问来源于stack exchange,提问作者mh9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:10:16