如何将未规范化的csv文件更改为复杂的JSON或Java对象

w7t8yxp5  于 2023-07-31  发布在  Java
关注(0)|答案(2)|浏览(144)

我有以下未规范化的csv文件

user_id,nickname,joinDate,product_id,price
1,kmh,2023-07-24,P131,3000
1,kmh,2023-07-24,P132,4000
1,kmh,2023-07-24,P133,7000
1,kmh,2023-07-24,P134,9000
2,john,2023-07-24,P135,2500
2,john,2023-07-24,P136,6000
3,alice,2023-07-25,P137,4500
3,alice,2023-07-25,P138,8000

字符串
我将把它改为下面的json格式(或java对象)。

[
    {
        "user_id": 1,
        "nickname": "kmh",
        "joinDate": "2023-07-24",
        "orders": [
            {
                "product_id": "P131",
                "price": 3000
            },
            {
                "product_id": "P132",
                "price": 4000
            },
            {
                "product_id": "P133",
                "price": 7000
            },
            {
                "product_id": "P134",
                "price": 9000
            }
        ]
    },
    {
        "user_id": 2,
        "nickname": "john",
        "joinDate": "2023-07-24",
        "orders": [
            {
                "product_id": "P135",
                "price": 2500
            },
            {
                "product_id": "P136",
                "price": 6000
            }
        ]
    },
    {
        "user_id": 3,
        "nickname": "alice",
        "joinDate": "2023-07-25",
        "orders": [
            {
                "product_id": "P137",
                "price": 4500
            },
            {
                "product_id": "P138",
                "price": 8000
            }
        ]
    }
]


我已经搜索了很长时间,还没有找到一个库或工具,使这一点。
我有这么多不同类型的csv,我需要工具或库来改变所有这些。是否有任何库或工具可以实现这一点?

q5lcpyga

q5lcpyga1#

对于您的情况,您可以直接将csv反序列化为JsonNode,而无需创建POJO类。然后使用JSON库 Josson 通过函数group()转换JSON。

String csv = "user_id,nickname,joinDate,product_id,price\n" +
        "1,kmh,2023-07-24,P131,3000\n" +
        "1,kmh,2023-07-24,P132,4000\n" +
        "1,kmh,2023-07-24,P133,7000\n" +
        "1,kmh,2023-07-24,P134,9000\n" +
        "2,john,2023-07-24,P135,2500\n" +
        "2,john,2023-07-24,P136,6000\n" +
        "3,alice,2023-07-25,P137,4500\n" +
        "3,alice,2023-07-25,P138,8000";
ArrayNode arrayNode = Josson.createArrayNode();
CsvSchema schema = CsvSchema.emptySchema().withHeader();
try (MappingIterator<JsonNode> it = new CsvMapper().readerFor(JsonNode.class).with(schema).readValues(csv)) {
    arrayNode.addAll(it.readAll());
}
Josson josson = Josson.create(arrayNode);
JsonNode grouped = josson.getNode(
        "group(map(user_id, nickname, joinDate), map(product_id, price))" +
        ".map(**:key, orders:elements)");
System.out.println(grouped.toPrettyString());

字符串

函数group()

1.按{user_id,nickname,joinDate}的“key”分组
1.具有{product_id,price}的“元素”

函数map()

1.提取对象“key”内部的值
1.添加从“元素”复制的字段“订单”

输出

[ {
  "user_id" : "1",
  "nickname" : "kmh",
  "joinDate" : "2023-07-24",
  "orders" : [ {
    "product_id" : "P131",
    "price" : "3000"
  }, {
    "product_id" : "P132",
    "price" : "4000"
  }, {
    "product_id" : "P133",
    "price" : "7000"
  }, {
    "product_id" : "P134",
    "price" : "9000"
  } ]
}, {
  "user_id" : "2",
  "nickname" : "john",
  "joinDate" : "2023-07-24",
  "orders" : [ {
    "product_id" : "P135",
    "price" : "2500"
  }, {
    "product_id" : "P136",
    "price" : "6000"
  } ]
}, {
  "user_id" : "3",
  "nickname" : "alice",
  "joinDate" : "2023-07-25",
  "orders" : [ {
    "product_id" : "P137",
    "price" : "4500"
  }, {
    "product_id" : "P138",
    "price" : "8000"
  } ]
} ]

n7taea2i

n7taea2i2#

您所需要的只是一种将CSV解析为Java对象的方法。您可以手动执行此操作,也可以使用现有库。
例如,您可以将Jackson与CSV数据格式一起使用,如下所示:

class MyRecord {

    @JsonProperty("user_id")
    private int userId;
    
    private String nickname;
    
    private LocalDate joinDate;

    @JsonProperty("product_id")
    private String productId;

    // getters and setters

    // a meaningful toString method

}

public class Main {

    public static void main(String[] args) throws IOException {
        String csv = "user_id,nickname,joinDate,product_id,price\n" +
                "1,kmh,2023-07-24,P131,3000\n" +
                "1,kmh,2023-07-24,P132,4000\n" +
                "1,kmh,2023-07-24,P133,7000\n" +
                "1,kmh,2023-07-24,P134,9000\n" +
                "2,john,2023-07-24,P135,2500\n" +
                "2,john,2023-07-24,P136,6000\n" +
                "3,alice,2023-07-25,P137,4500\n" +
                "3,alice,2023-07-25,P138,8000";

        CsvSchema schema = CsvSchema.emptySchema().withHeader(); // uses CSV header to read the schema
        ObjectMapper mapper = new CsvMapper().registerModule(new JavaTimeModule()); // to deserialise Java 8 LocalDate
        MappingIterator<MyRecord> resultIterator = mapper.readerFor(MyRecord.class).with(schema).readValues(csv);
        while (resultIterator.hasNext()) {
            System.out.println(resultIterator.next());
        }
        resultIterator.close();
    }
}

字符串
哪些打印:

MyRecord[userId=1, nickname='kmh', joinDate=2023-07-24, productId='P131', price=3000]
MyRecord[userId=1, nickname='kmh', joinDate=2023-07-24, productId='P132', price=4000]
MyRecord[userId=1, nickname='kmh', joinDate=2023-07-24, productId='P133', price=7000]
MyRecord[userId=1, nickname='kmh', joinDate=2023-07-24, productId='P134', price=9000]
MyRecord[userId=2, nickname='john', joinDate=2023-07-24, productId='P135', price=2500]
MyRecord[userId=2, nickname='john', joinDate=2023-07-24, productId='P136', price=6000]
MyRecord[userId=3, nickname='alice', joinDate=2023-07-25, productId='P137', price=4500]
MyRecord[userId=3, nickname='alice', joinDate=2023-07-25, productId='P138', price=8000]

相关问题