使用java根据键值拆分JSON文件中的数据
Posted
技术标签:
【中文标题】使用java根据键值拆分JSON文件中的数据【英文标题】:Split data in JSON file based on a key value using java 【发布时间】: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 处遇到错误,但这不是我的主要问题,我真正想要一种方法来拆分它们我尝试了几件事没有奏效
【问题讨论】:
【参考方案1】:一般来说,您违反了单一职责原则 (SOLID),因为您的代码一起做了两件不同的事情:解析文件和对项目进行分类。你应该分担这些责任。
其中一种方法是创建代表数据的类。假设这些类是Item
、Category
、Order
和CategorizedItems
。 Order
是一个类,代表您的源 JSONObject
和 CategorizedItems
- 代表您的结果 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;
【讨论】:
以上是关于使用java根据键值拆分JSON文件中的数据的主要内容,如果未能解决你的问题,请参考以下文章