1

我有由 HashMap 支持的 java 对象,因此没有可以通过反射发现的普通字段。例如:

public class City {
    private final HashMap<String, String> internalMap = new HashMap<String, String>();

    public String getId() {
        return internalMap.get("id");
    }

    public void setId(String id) {
        internalMap.put("id", id);
    }

    public String getName() {
        return internalMap.get("name");
    }

    public void setName(String name) {
        internalMap.put("name", name);
    }
}

我想在 Room 中使用诸如此类的实体,而不必更改其结构,因为我有许多此类使用代码生成工具自动生成的类,并且有特定原因需要 HashMap 支持它们。HashMap 的每个值最终都应作为我的数据库表中的一列(键 String 是内部实现细节)。可能吗?由于注释处理器如何发现字段,目前似乎不是。

更新:

没有一个答案是我想要的。我打开了一个新问题而没有提及 HashMap,因为该细节不应该是相关的,但所有答案都锁定在它上面。请参阅如何将 Android Room 与外部库提供的 POJO 一起使用?对于更新的问题。

4

2 回答 2

0

Room 有它自己的一组注释——如果你不想映射一个字段,你必须通过注释 POJO 来向注释处理器表明这一点,因为它可能是需要的;例如。@Entity没有分配 a tableName,以及@Ignore上面要忽略的字段:

@Entity
public class City {

    @Ignore
    private final HashMap<String, String> internalMap = new HashMap<>();

    /* concerning the second part of the question: */
    public HashMap<String, Object> toHashMap() {
        return this.internalMap;
    }
}

除了那些 getter 有一个基本问题,他们假设所有的键都存在,尽管HashMap可能没有填充所有(或任何)这些键。用两种不同类型的对象来表示一个城市是荒谬的 - 而一个可以完全控制哪些字段被映射,哪些被忽略(一种可能的方法不必在这里排除另一种)......一种返回的方法HashMap可能有用,例如。以便将其插入 Firebase。

我宁愿选择保存值的字段,但仍然能够返回HashMap

@Entity(tableName = "cities")
public class City {

    @ColumnInfo(name = "cityId")
    @PrimaryKey(autoGenerate = true)
    private int cityId = -1;

    @ColumnInfo(name = "cityName")
    private String cityName = null;

    ...

    /* concerning the second part of the question: */
    public HashMap<String, Object> toHashMap() {
        HashMap<String, Object> values = new HashMap<>();
        if(this.cityId   !=   -1) {values.put(  "id", this.cityId);}
        if(this.cityName != null) {values.put("name", this.cityName);}
        return values;
    }
}

这样的toHashMap()方法还提供控制,返回的字段HashMap应包含哪些字段,而带有TypeConverter&的示例GSON将(按原样)转换整个HashMap.

于 2018-08-17T22:52:56.710 回答
0

您可以为此使用 TypeConverter。例如,您可以使用 GSON 提供的序列化来轻松地将映射转换为序列化状态,反之亦然。

class MapConverter {
    @TypeConverter
    public String fromMap(HashMap<String, String> map) {
        return new Gson().toJson(map);
    }

    @TypeConverter
    public HashMap<String, String> fromString(String serializedMap) {
        Type type = new TypeToken<HashMap<String, String>>(){}.getType();
        return gson.fromJson("serializedMap", type);
    }
}

在您的实体类中:

@Entity
@TypeConverters({MapConverter.class})
public class CityEntity {
//...
private final HashMap<String, String> internalMap;
//...
}

因此,该实体可以使用转换器将哈希图序列化为字符串,反之亦然。Gson 只是一个可能的解决方案,您实际上可以使用任何您想要的。

于 2018-08-17T21:25:09.810 回答