【问题标题】:Split data in JSON file based on a key value using java使用java根据键值拆分JSON文件中的数据
【发布时间】:2022-01-20 04:28:59
【问题描述】:

我有一个 json 文件,其中有一个产品项目数组,我想根据项目的类别将它们拆分, 这是我的 json 文件的样子,

{
    "items":[
        {
            "item-id": 123,
            "name": "Cheese",
            "price": 8,
            "category": "Dairy" 
        },
        {
            "item-id": 124,
            "name": "Milk",
            "price": 23,
            "category": "Dairy"
        },
        {
            "item-id": 125,
            "name": "Chicken",
            "price": 100,
            "category": "Meat"
        },
        {
            "item-id": 126,
            "name": "Fish",
            "price": 45,
            "category": "Meat"
        }
    ]
}

我想像这样拆分它们,

[
    {
        "category":"Dairy",
        "items":[
            {
                "item-id": 123,
                "name": "Cheese",
                "price": 8,
                "category": "Dairy" 
            },
            {
                "item-id": 124,
                "name": "Milk",
                "price": 23,
                "category": "Dairy"
            }
        ]
    },
    {
        "category":"Meat",
        "items":[
            {
                "item-id": 125,
                "name": "Chicken",
                "price": 100,
                "category": "Meat"
            },
            {
                "item-id": 126,
                "name": "Fish",
                "price": 45,
                "category": "Meat"
            }
        ]
    }
]

这是我迄今为止尝试过的代码,但找不到像我想要的那样拆分它们的方法,我正在使用 java,而且我也是 java 新手

import java.io.*; 
import java.util.*;
import org.json.simple.*;
import org.json.simple.parser.*;

public class ReadOrderDetails {

    @SuppressWarnings("unused")
    public static void main(String[] args) {
        JSONParser parser = new JSONParser();
        JSONObject subOrder = new JSONObject();
        JSONArray  gitems = new JSONArray();
        JSONArray  subOrders = new JSONArray();
        
        try {
            Object obj = parser.parse(new FileReader("order-details.json"));
            JSONObject jsonObject = (JSONObject)obj;
            String orderId = (String)jsonObject.get("orderId");
            JSONArray items = (JSONArray)jsonObject.get("items");
            @SuppressWarnings("rawtypes")
            Iterator iterator = items.iterator();
            System.out.println("Order Id: " + orderId);
            while(iterator.hasNext()) {
                JSONObject item = (JSONObject)iterator.next();
                if(subOrders.isEmpty()) {
                    subOrder.put("category", item.get("category"));
                    gitems.add(item);
                    subOrder.put("items", gitems);
                    subOrders.add(subOrder);
                } else {
                    Iterator subOrdersIterator = subOrders.iterator();
                    for(int i=0; i<subOrders.size(); i++) {
                        JSONObject sitem = (JSONObject) subOrdersIterator.next();
                        if(sitem.get("category") == item.get("category")) {
                            gitems.add(item);
                            subOrder.put("items", gitems);
                            subOrders.add(subOrder);
                        } else {
                            subOrder.put("category", item.get("category"));
                            gitems.add(item);
                            subOrder.put("items", gitems);
                            subOrders.add(subOrder);
                        }
                    }
                }
                
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
        System.out.println(subOrders);
    }

}



而且我在 java.util.ConcurrentModificationException 处遇到错误,但这不是我的主要问题,我真正想要一种方法来拆分它们我尝试了几件事没有奏效

【问题讨论】:

    标签: java json


    【解决方案1】:

    一般来说,您违反了单一职责原则 (SOLID),因为您的代码一起做了两件不同的事情:解析文件和对项目进行分类。你应该分担这些责任。

    其中一种方法是创建代表数据的类。假设这些类是ItemCategoryOrderCategorizedItemsOrder 是一个类,代表您的源 JSONObjectCategorizedItems - 代表您的结果 JSONArray

    在这种情况下,您应该首先将文件解析为这些类,然后再将它们转换为JSONArray

    代码示例:

    数据类:

    class Order {
        private final List<Item> items = new ArrayList<>();
    
        public void addItem(Item item) {
            items.add(item);
        }
    
        public List<Item> getAllItems() {
            return new ArrayList<>(items);
        }
    }
    
    enum Category {
        DAIRY("Dairy"),
        MEAT("Meat");
    
        private final String value;
    
        Category(String value) {
            this.value = value;
        }
    
        public String getValue() {
            return value;
        }
    
        public static Category of(String value) {
            for (Category category : values()) {
                if (category.value.equals(value)) {
                    return category;
                }
            }
    
            throw new IllegalArgumentException("Unknown category");
        }
    }
    
    class CategorizedItems {
        private final Category category;
        private final List<Item> items;
    
        public CategorizedItems(Category category, List<Item> items) {
            this.category = category;
            this.items = items;
        }
    
        public Category getCategory() {
            return category;
        }
    
        public List<Item> getItems() {
            return items;
        }
    }
    class Item {
        private final long id;
        private final String name;
        private final long price;
        private final Category category;
    
    
        public Item(long id, String name, long price, Category category) {
            this.id = id;
            this.name = name;
            this.price = price;
            this.category = category;
        }
    
        public long getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public long getPrice() {
            return price;
        }
    
        public Category getCategory() {
            return category;
        }
    }
    

    现在您应该在ReadOrderDetails 中编写方法,例如静态方法:

        private static JSONArray categorizedItemsToJSONArray(List<CategorizedItems> categorizedItems) {
            JSONArray jsonArray = new JSONArray();
            categorizedItems.forEach(category -> jsonArray.add(toJSONObject(category)));
    
            return jsonArray;
        }
    
        private static JSONObject toJSONObject(CategorizedItems categorizedItems) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("category", categorizedItems.getCategory().getValue());
            jsonObject.put("items", itemsToJSONArray(categorizedItems.getItems()));
    
            return jsonObject;
        }
    
        private static JSONArray itemsToJSONArray(List<Item> items) {
            JSONArray jsonArray = new JSONArray();
            items.forEach(item -> jsonArray.add(toJSONObject(item)));
    
            return jsonArray;
        }
    
        private static JSONObject toJSONObject(Item item) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("item-id", item.getId());
            jsonObject.put("name", item.getName());
            jsonObject.put("price", item.getName());
            jsonObject.put("category", item.getCategory().getValue());
    
            return jsonObject;
        }
    
    
        private static List<CategorizedItems> categorize(Order order) {
            List<CategorizedItems> categorizedItems = new ArrayList<>();
            for (Category category : Category.values()) {
                categorizedItems.add(
                        new CategorizedItems(
                                category,
                                order.getAllItems()
                                        .stream()
                                        .filter(item -> item.getCategory() == category)
                                        .collect(Collectors.toList())
                        )
                );
            }
    
            return categorizedItems;
        }
    
        private static Order orderFrom(JSONObject jsonObject) {
            JSONArray itemsJsonArray = (JSONArray) jsonObject.get("items");
    
            Order order = new Order();
            for (Object jsonArrayMember : itemsJsonArray) {
                JSONObject itemJsonObject = (JSONObject) jsonArrayMember;
                order.addItem(itemFrom(itemJsonObject));
            }
    
            return order;
        }
    
        private static Item itemFrom(JSONObject jsonObject) {
            long itemId = (Long) jsonObject.get("item-id");
            String itemName = (String) jsonObject.get("name");
            long itemPrice = (Long) jsonObject.get("price");
            Category category = Category.of((String) jsonObject.get("category"));
    
            return new Item(
                    itemId,
                    itemName,
                    itemPrice,
                    category
            );
        }
    

    之后,您应该执行最后一步。编写一个主函数,如:

        public static void main(String[] args) {
            JSONParser parser = new JSONParser();
    
    
            try {
                JSONObject orderJsonObject = (JSONObject) parser.parse(new FileReader("order-details.json"));
                Order order = orderFrom(orderJsonObject);
                List<CategorizedItems> categorizedItems = categorize(order);
                JSONArray categorizedItemsJsonArray = categorizedItemsToJSONArray(categorizedItems);
    
                // write categorizedItemsJsonArray to a file here
            } catch(IOException | ParseException e) {
                throw new RuntimeException(e);
            }
        }
    

    现在您的代码简单易读且清晰。您可以轻松维护它。我建议您阅读有关 SOLID 原则和代码风格的信息(我强烈推荐 Robert Martin。“清洁代码”)。这些主题将帮助您学习如何编写优雅而清晰的代码。

    此外,ConcurrentModificationException 表示您在收藏方面做错了事。在您的特定情况下,我猜(不确定)问题是在您迭代 JSONArray 时对其进行了修改。只有部分 Java 集合允许。

    编辑通过将整数替换为 long 来解决整数问题。

    祝 Java 好运 :)

    【讨论】:

    • 得到这个错误 class java.lang.Long 不能从第一行 ``itemFrom``` 转换为 class java.lang.Integer
    • @AbhijithEA 很有趣。我会根据这个错误按答案编辑
    【解决方案2】:

    您不能在迭代集合时更改它。试试这个:

                    Object[] subOrderArray = subOrders.toArray();
                    for(Object o: subOrderArray) {
                        JSONObject sitem = (JSONObject) o;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-13
      • 2022-11-14
      • 1970-01-01
      • 2020-11-12
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 2017-10-10
      相关资源
      最近更新 更多