对象类型在赋值后仍然保持为LinkedHashMap。

huangapple go评论64阅读模式
英文:

Object type remains as LinkedHashMap after assignment

问题

我有以下JSON数据从外部文件源获取:

{
    .... JSON格式中的更复杂结构,但我只关心以下部分
    "feature": {
        "100": {
            "DATA1": [
                {
                    "header": "head1",
                    "someId": "123"
                }
            ]
        }
    }
}

我尝试捕获以下部分作为List <Data>

"DATA1": [
    {
        "header": "head1",
        "someId": "123"
    }
]

但无法做到。出现以下错误:

> 无法将LinkedHashMap转换为List。

获取数据并尝试将其分配给List<Data>的方法:

private void getData(){
    AllDataFromFile all = someFetchAPI(); // 从文件中获取了每个JSON数据。

    // 获取我想要的部分,我确实得到了它。
    Map<String, Map<String,Object>> feature = all.getFeature(); 
    Map<String, Object> allData = feature.get("100");
    List<Data> dataList = allData.get("DATA1");
}

以上既没有编译错误也没有运行时错误,但dataList不是List<Data>

实际上,在调试模式下,它是一个LinkedHashMap的列表。为什么?如何将其转换为List<Data>

由于它不能映射为List<Data>,因此我无法执行以下操作。

dataList.get(0).getHeader().

无法将其强制转换,也出现相同错误:

> 无法将LinkedHashMap转换为List。

请给予建议。谢谢。

AllDataFromFile类:

@Getter
@Setter
@JsonInclude(Include.NON_NULL)
public class AllDataFromFile {
    private Map<String, Map<String,Object>> feature;
}

Data类:

@JsonInclude(Include.NON_NULL)
public class Data implements Comparable<Data>, Cloneable{	
    private String header;
    private String someId;

    @Override
    public int compareTo(Data o) {
        int result = // 一些逻辑
        return result;
    }	
}

编辑:

这是List<Data>内部的数据格式:

result = {ArrayList@18590} size = 1
  0 = {LinkedHashMap@18593} size = 2
    "header" -> "header1"
    "someId" -> "id1"

当我尝试将对象的值与更具体的类型匹配时,会出现以下错误。

private Map<String, Map<String, List<Data>>> feature;

如果我尝试以下内容,将回到获取LinkedHashMap的情况(没有用,回到起点):

private Map<String, Map<String, List>> feature;

错误:

> 无法读取JSON:Class java.util.LinkedHashMap不是 [简单类型,类com.a.a.a.a.a.Data] 的子类型(通过引用链:com.b.b.b.b.b.b.AllDataFromFile["feature"]->java.util.LinkedHashMap["100"]->java.util.LinkedHashMap["DATA1"]->java.util.ArrayList[0])。
英文:

I have the following JSON data being fetched from an external file source.

{
    .... More complicated structures within this JSON format above but I only care about the following
    &quot;feature&quot;: {
        &quot;100&quot;: {
            &quot;DATA1&quot;: [
                {
                    &quot;header&quot;: &quot;head1&quot;,
                    &quot;someId&quot;: &quot;123&quot;
                }
            ]
        }
    }
}

I am trying to capture the following portion as List < Data >

&quot;DATA1&quot;: [
    {
        &quot;header&quot;: &quot;head1&quot;,
        &quot;someId&quot;: &quot;123&quot;
    }
]

but unable to do so. Getting following error:

> Cannot cast LinkedHashMap to List.

Method which fetched the data and try to assign it to List< Data >

private void getData(){
    AllDataFromFile all = someFetchAPI(); // Got every JSON data in the file. 

    // capturing the portion that I want which I do get. 
    Map&lt;String, Map&lt;String,Object&gt;&gt; feature = all.getFeature(); 
    Map&lt;String, Object&gt; allData = feature.get(&quot;100&quot;);
    List&lt;Data&gt; dataList = allData.get(&quot;DATA1&quot;);
}

No compilation nor run time errors from above but dataList is not a List of Data.

Instead it is a List of LinkedHashMap when I see in debug mode. Why?
And how can I turn this into a List of Data instead?

Since it doesn't map as a List< Data >, I am unable to perform operations such as follows.

dataList.get(0).getHeader(). 

Unable to cast it either and getting same error:

> Cannot cast LinkedHashMap to List.

Please advice. Thanks.

AllDataFromFile class

@Getter
@Setter
@JsonInclude(Include.NON_NULL)
public class AllDataFromFile {
	private Map&lt;String, Map&lt;String,Object&gt;&gt; feature;
}

Data class

@JsonInclude(Include.NON_NULL)
public class Data implements Comparable&lt;Data&gt;, Cloneable{	
	private String header;
    private String someId;

    @Override
	public int compareTo(Data o) {
        int result = // some logic
		return result;
	}	
}

EDIT:

This is data format inside List<Data>

result = {ArrayList@18590} size = 1
  0 = {LinkedHashMap@18593} size = 2
    &quot;header&quot; -&gt; &quot;header1&quot;
    &quot;someId&quot; -&gt; &quot;id1&quot;

Getting following error when I try to match the Object's value to be more specific as follows.

private Map&lt;String, Map&lt;String, List&lt;Data&gt;&gt;&gt; feature;

Able to go back to getting LinkedHashMap (no use, back to Square one) if I go for the following:

private Map&lt;String, Map&lt;String, List&gt;&gt; feature;

Error:

> Could not read JSON: Class java.util.LinkedHashMap not subtype of
> [simple type, class com.a.a.a.a.a.Data] (through reference chain:
> com.b.b.b.b.b.b.AllDataFromFile["feature"]->java.util.LinkedHashMap["100"]->java.util.LinkedHashMap["DATA1"]->java.util.ArrayList[0])

答案1

得分: 1

以下是翻译好的内容:

Jackson使用反射来确定它需要反序列化的类型。

但是从AllDataFromFile开始,它无法确定内容实际上是一个Data对象列表,因此它会退回到默认的列表(ArrayList)和映射(LinkedHashMap)。

我认为如果您在类型声明中提供更多信息,Jackson可能会弄清楚:

public class AllDataFromFile {
    private Map<String, Map<String, List<Data>>> feature;
}
英文:

Jackson uses reflection to determine what type it needs to deserialize too.

But starting from AllDataFromFile, it cannot determine that the content is actually a List of Data objects, so it falls back to default Lists (ArrayList) and Maps(LinkedHashMap).

I think if you provide more information in the type declaration, jackson might figure it out:

public class AllDataFromFile {
    private Map&lt;String, Map&lt;String, List&lt;Data&gt;&gt;&gt; feature;
}

huangapple
  • 本文由 发表于 2020年4月9日 23:21:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/61124547.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定