程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Gson:要列出的索引对象大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决Gson:要列出的索引对象?

开发过程中遇到Gson:要列出的索引对象的问题如何解决?下面主要结合日常开发的经验,给出你关于Gson:要列出的索引对象的解决方法建议,希望对你解决Gson:要列出的索引对象有所启发或帮助;

我有一个来自外部 API 的 Json 对象,它具有以下形式的对象“列表”:

cons@R_197_9829@nts {
    implementation('androIDx.fragment:fragment:1.3.1') {
        because 'avoID BUG'
    }
    implementation('androIDx.fragment:fragment-ktx:1.3.1') {
        because 'avoID BUG'
    }
}

我的解串器和 POJO 看起来像这样

{
  "wIDth": 10,"height": 20
  "pointData": {
    "0": {
      "x": 7,"y": 5,...
    },"1": {
      "x": 4,"y": 20,"2": {
      "x": 1,"y": 3,...
  }
}

由于 class KeyedListDeserializer<T> implements JsonDeserializer<List<T>> { @OverrIDe public List<T> deserialize(JsonElement Json,Type typeOfT,JsonDeserializationContext context) throws JsonParseException { JsonObject JsonObject = Json.getAsJsonObject(); List<T> things = new ArrayList<>(); int key = 0; while (JsonObject.has(String.valueOf(key))) { JsonElement element = JsonObject.get(String.valueOf(key)); T value = context.deserialize(element,new Typetoken<T>(){}.getType()); things.add(value); key += 1; } return things; } } class PointDataKeyedList extends KeyedListDeserializer<PointData> {} class Canvas { int wIDth; int height; @JsonAdapter(PointDataKeyedList.class) List<PointData> pointData; ... } class PointData { int x; int y; ... } 对象的所有键都只是索引,我认为我可以将其反序列化为列表而不是映射。运行时,Gson 成功通过反序列化,但是当我尝试访问点数据时,我得到:

pointData

我不确定这里出了什么问题。我读过一些关于类型擦除的文章,这是我在搜索这个问题时听到的很多内容,但我不是很理解。

解决方法

在 Gson 中很容易。

from SELEnium import webdriver
from SELEnium.webdriver import ActionChains

driver = webdriver.Chrome()
url = 'https://www.target.com/p/prairie-farms-vitamin-d-milk-1gal/-/A-47103206#lnk=sametab'
driver.get(url)
driver.implicitly_wait(5)

elements = driver.find_elements_by_xpath("//a[contains(@class,'TabHeader__Styled')]")
for el in elements:
    ActionChains(driver).move_to_element(el).perform()
    el.click()

driver.quit()

上面的类型适配器工厂做了以下事情:

  • 检查目标类型是否为public final class MapToListTypeAdapterFactory implements TypeAdapterFactory { private MapToListTypeAdapterFactory() { } @Override @Nullable public <T> TypeAdapter<T> create(final Gson gson,final TypeToken<T> typeToken) { if ( !List.class.isAssignableFrom(typeToken.getRawType()) ) { return null; } final Type elementType = typeToken.getType() instanceof ParameterizedType ? ((ParameterizedTypE) typeToken.getType()).getActualTypeArguments()[0] : Object.class; final TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementTypE)); final TypeAdapter<List<Object>> listTypeAdapter = new TypeAdapter<List<Object>>() { @Override public void write(final JsonWriter out,final List<Object> value) { throw new UnsupportedoperationException(); } @Override public List<Object> read(final JsonReader in) throws IOException { in.beginObject(); final ArrayList<Object> list = new ArrayList<>(); while ( in.hasNext() ) { final int index = Integer.parseInt(in.nextName()); final Object element = elementTypeAdapter.read(in); ensureSize(list,index + 1); list.set(index,element); } in.endObject(); return list; } }; @SuppressWarnings("unchecked") final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) listTypeAdapter .nullSafe(); return typeAdapter; } // https://stackoverflow.com/questions/7688151/java-arraylist-ensurecapacity-not-working/7688171#7688171 private static void ensureSize(final ArrayList<?> list,final int sizE) { list.ensureCapacity(sizE); while ( list.size() < size ) { list.add(null); } } } 它实际上不适用于链表,但可以简化);
  • 提取目标列表的类型参数,因此其元素类型并解析相应的类型适配器;
  • 用地图读取适配器替换原始类型适配器,该适配器读取地图键并将它们假定为新列表索引(并在必要时扩大结果列表)并使用原始元素类型适配器读取每个地图值。请注意,列表可能具有稀疏索引的假设是易受攻击的,我仅将其用于演示目的(例如,输入 JSON 声明了一个单元素映射,其中唯一的索引“999999”可显着扩大列表),因此您可以仅使用 List 方法忽略 index 值。

只需使用 add(element) 注释 pointData 类中的 Canvas 字段,它就会起作用。

,

我担心你的 POJO 类需要像

class Canvas {
  int width;
  int height;
  Map<String,PointData> pointData;
  ...
}

class PointData {
  int x;
  int y;
  ...
}

你可以去掉 PointDataKeyedList 和 KeyedListDeserializer

public static void main(String[] args) {
        String json = "{\n" +
                "  \"width\": 10,\n" +
                "  \"height\": 20,\n" +
                "  \"pointData\": {\n" +
                "    \"0\": {\n" +
                "      \"x\": 7,\n" +
                "      \"y\": 5\n" +

                "    },\n" +
                "    \"1\": {\n" +
                "      \"x\": 4,\n" +
                "      \"y\": 20\n" +
                "    },\n" +
                "    \"2\": {\n" +
                "      \"x\": 1,\n" +
                "      \"y\": 3\n" +
                "    }\n" +
                "  }\n" +
                "}";

        System.out.println(json);
        Gson gson = new Gson();
        Canvas canvas = gson.fromJson(json,Canvas.class);
        System.out.println(canvas);
}

Gson:要列出的索引对象

大佬总结

以上是大佬教程为你收集整理的Gson:要列出的索引对象全部内容,希望文章能够帮你解决Gson:要列出的索引对象所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: