我有两个描述所有数据的类和一个描述数据类型的枚举
class Category(val name: String,
val id: String,
val type: CategoryType,
val items: List<Item>)
class Item(val name: String,
val id: String,
val type: CategoryType,
val data: Any?,
val categoryIds: Array<String>)
enum class CategoryType {
TYPE_A,
TYPE_B,
TYPE_C
}
并遵循JSON输入
{
"categories": [
{
"id": "category_id_1",
"name": "Category 1",
"type1": "TYPE_A",
"type2": "TYPE_C"
},
{
"id": "category_id_2",
"name": "Category 2",
"type1": "TYPE_B"
},
{
"id": "category_id_3",
"name": "Category 3",
"type1": "TYPE_A"
},
{
"id": "category_id_4",
"name": "Category 4",
"type1": "TYPE_C"
}
],
"items": [
{
"id": "item_id_1",
"name": "Item 1",
"type2": "TYPE_A",
"categoryIds": [
"category_id_4",
"category_id_3"
]
},
{
"id": "item_id_2",
"name": "Item 2",
"type1": "TYPE_C",
"categoryIds": [
"category_id_1"
]
}
]
}
有两个主要要求:
Category
的实例,如果有的话id
在那里列出了type1
和type2
。Item
和/或Category
和type1
的{{},我需要在每个type2
个实例中放置Category
的相同实例1}}列在id
的{{1}}。对于每个Item
,我可以使用任何类型的容器,例如categoryIds
。
所以问题是:如果不使用庞大的CategoryType
构造,我怎么能这样做呢?是否可以使用val typedAsTYPE_A: List<Category>
完成,或者我应该使用类似com.google.gson.JsonDeserializer
的内容?
答案 0 :(得分:0)
这适用于您提供的Json。
Gson gson = new Gson();
String json = YOURJSON
ContainerObject myObj = gson.fromJson(json, ContainerObject.class);
//above code is placed where you want to deserialize the object
import java.util.ArrayList;
public class ContainerObject {
private ArrayList<Categories> categories;
private ArrayList<Item> items;
public ContainerObject(){
}
public ArrayList<Categories> getCategories() {
return categories;
}
public void setCategories(ArrayList<Categories> categories) {
this.categories = categories;
}
public ArrayList<Item> getItems() {
return items;
}
public void setItems(ArrayList<Item> items) {
this.items = items;
}
}
import java.util.List;
public class Categories {
private String id;
private String name;
private CategoryType type1;
private CategoryType type2;
public Categories(){
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CategoryType getType1() {
return type1;
}
public void setType1(CategoryType type1) {
this.type1 = type1;
}
public CategoryType getType2() {
return type2;
}
public void setType2(CategoryType type2) {
this.type2 = type2;
}
}
import java.util.ArrayList;
public class Item {
private String id;
private String name;
private CategoryType type1;
private CategoryType type2;
private ArrayList<String> categoryIds;
public Item(){
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CategoryType getType1() {
return type1;
}
public void setType1(CategoryType type1) {
this.type1 = type1;
}
public CategoryType getType2() {
return type2;
}
public void setType2(CategoryType type2) {
this.type2 = type2;
}
public ArrayList<String> getCategoryIds() {
return categoryIds;
}
public void setCategoryIds(ArrayList<String> categoryIds) {
this.categoryIds = categoryIds;
}
}
public enum CategoryType {
TYPE_A,
TYPE_B,
TYPE_C
}
答案 1 :(得分:0)
免责声明:我对Gson并不熟悉,但既然你想使用它,我就试着把它放在一起。最有可能有更好的方法来实现相同的结果。代码可能不健壮,可能包含错误。
我希望我的代码足够可理解。基本上就是这些步骤:
以下是代码:
// Helper extension property for easily mapping Strings
// to their enum CategoryType
val String.catType: CategoryType?
get() = CategoryType.values().find { it.toString() == this }
fun deserialize(json: String): Map<CategoryType, List<Category>> {
// initialize the return value
val categories = CategoryType.values().map { it to (mutableListOf<Category>()) }.toMap()
// parse json
val input = Gson().fromJson(json, com.google.gson.JsonObject::class.java)
// accumulate itemLists for constructing Categories later
// those lists will be looked up via CategoryType and CategoryId
val itemLists = CategoryType.values().map { it to (mutableMapOf<String, MutableList<Item>>()) }.toMap()
input["items"].asJsonArray.map { it.asJsonObject }.forEach { item ->
// read properties for item
val types = item.entrySet().filter { it.key.startsWith("type") }.map { it.value.asString.catType }
val ids = item.getAsJsonArray("categoryIds").map { it.asString }
val name = item["name"].asString
val item_id = item["id"].asString
val data = item["data"]
//
types.forEach { type ->
type?.let {
val itemObj = Item(name, item_id, type, data, ids.toTypedArray())
ids.forEach { id ->
with(itemLists[type]!!) {
if (!this?.containsKey(id)) this[id] = mutableListOf(itemObj)
else this[id]?.add(itemObj)
}
}
}
}
}
// go through all categories and create appropriate objects
input["categories"].asJsonArray.map { it.asJsonObject }.forEach { cat ->
val id = cat["id"].asString
val name = cat["name"].asString
val types = cat.entrySet().filter { it.key.startsWith("type") }.map { it.value.asString.catType }
types.forEach { type ->
type?.let {
categories[type]
?.add(Category(
name = name,
id = id,
type = type,
items = itemLists[type]?.get(id) ?: listOf()))
}
}
}
return categories
}