简体   繁体   English

使用 POJO 对象类将 JSON 解析为 POJO 对象列表

[英]Parse JSON to list of POJO objects using POJO object class

I am forced to use an interface method with the signature which I can not change:我被迫使用带有我无法更改的签名的接口方法:

List parse(String path, Class clazz)

It is supposed to return a list of objects with the type, passed in the clazz parameter, eg:它应该返回具有类型的对象列表,在clazz参数中传递,例如:

List<TagsRun> runs = reader.parse(path, TagsRun.class)

I need to implement a JSON parser and the question is how to set the type of clazz parameter to the result list?我需要实现一个 JSON 解析器,问题是如何将clazz参数的类型设置为结果列表?

I use Gson and it might be something like:我使用 Gson,它可能是这样的:

List parse(String path, Class clazz) {
    Type collectionType = new TypeToken<List<TagsRun>>(){}.getType();
    List<TagsRun> myList = new Gson.fromJson(json, collectionType);
    return myList 
}

But how to replace the particular List< TagsRun > with List< type of clazz > here?但是如何在这里用List< type of clazz >替换特定的List< TagsRun >

The only working solution I did requires changing of the method signature:我所做的唯一可行的解​​决方案需要更改方法签名:

<T> List<T> parse(String path, Class<T[]> clazz ) {
        T[] arr = new Gson().fromJson(new File(path).text(), clazz);
        return Arrays.asList(arr);
}

In other words, how to return the list of objects having the same type as clazz argument using the signature:换句话说,如何使用签名返回与clazz参数具有相同类型的对象列表:

 List parse(String path, Class clazz)

Thanks in advance.提前致谢。

Since you can not change the method's signature, there is no point in returning a List with type parameter.由于您无法更改方法的签名,因此返回带有类型参数的 List 毫无意义。

public List foo() {
    ArrayList<String> strings = new ArrayList<>();
    return strings;
}

public void methodUsingFoo() {
    // possible but you should check if the assumption is correct:
    List<String> uncheckedAssignment = foo(); // so don't do this

    // this is what foo *will* return:
    List actualResult = foo();
}

Instead you could do something like this:相反,您可以执行以下操作:

public void methodUsingParse() {
    Class clazz = Object.class; // or whatever class you want or need

    // this is what your method *will* return:
    List actualResult = parse("/path/to/somewhere", clazz);

    // best way would be to check each element:
    for(Object element : actualResult) {
        if (clazz.equals(element.getClass())) {
            // do your stuff here
        }
    }
}

What I forgot: I don't think that it es even possible to do this like you would like to.我忘记了什么:我认为甚至不可能像你想的那样做这件事。

Maybe convert the list?也许转换列表?

List<TagsRun> myList = new Gson.fromJson(json, collectionType);
List<Clazz> = Arrays.asList(myList.toArray(new Clazz[0]));

Edit: I think this could help you: https://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#checkedCollection(java.util.Collection,%20java.lang.Class) - Scroll down to the List section, if you didn't notice it编辑:我认为这可以帮助你: https : //docs.oracle.com/javase/6/docs/api/java/util/Collections.html#checkedCollection(java.util.Collection,%20java.lang.Class) - 如果您没有注意到,请向下滚动到列表部分

Solved it, finally:解决了,终于:

@Override
List parse(String path, Class clazz) {
    List result = []
    JsonArray jsonArray = new JsonParser()
            .parse(new File(path).getText(CHARSET))
            .getAsJsonArray()

    Gson gson = new Gson()
    jsonArray.each {
        result.add(gson.fromJson(it, clazz))
    }
    return result
}

The trick is to first get an array, and then use gson.fromJson(it, clazz) for each of array items.诀窍是首先获取一个数组,然后对每个数组项使用gson.fromJson(it, clazz) This will convert each json element in the array to POJO and then add it to result list.这会将数组中的每个 json 元素转换为 POJO,然后将其添加到结果列表中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM