类似字典的数据结构。这是一个好习惯吗? [英] Dictionary-like data structure. Is this a good practice?
问题描述
我需要一个数据结构来存储不同类型的对象。 String
,布尔值
和其他类。
使用 Map< ; String,Object>
其中使用你获得相应对象的键,假设你知道如何投掷它一个很好的做法?
有更好的解决方案吗?
I need a data structure to store different type of objects.E.g. String
, Boolean
and other classes.
Is using a Map<String, Object>
where using the key you get the according object which assumes that you know how to cast it a good practice?
Is there a better solution?
推荐答案
这是一个完美的用例,一段时间以前写过的 PropretyHolder
您可以在我的博客上阅读更多信息。我开发了它与不变性的心灵,随意适应你的需要。
That's a perfect use case for a PropretyHolder
I wrote a while ago. You can read in length about it on my blog. I developed it with immutability in mind, feel free to adapt it to your needs.
一般来说,我想说如果你想从Java中的类型安全性中获利知道你的钥匙我的意思是 - 几乎不可能开发类型的安全解决方案,其中钥匙来自外部来源。
In general I'd say if you want to profit from type safety in Java you need to know your keys. What I mean by that - it will be hardly possible to develop type safe solution where keys come from external source.
这里是知道其价值类型的特殊键(不完整,请下载源完整版本):
Here's a special key that knows type of its value (it's not complete please download the source for complete version):
public class PropertyKey<T> {
private final Class<T> clazz;
private final String name;
public PropertyKey(Class<T> valueType, String name) {
this.clazz = valueType;
this.name = name;
}
public boolean checkType(Object value) {
if (null == value) {
return true;
}
return this.clazz.isAssignableFrom(value.getClass());
}
... rest of the class
}
然后你开发一个利用它的数据结构:
Then you develop a data structure that utilizes it:
public class PropertyHolder {
private final ImmutableMap<PropertyKey<?>, ?> storage;
/**
* Returns value for the key of the type extending-the-one-declared-in-the {@link PropertyKey}.
*
* @param key {@link PropertyKey} instance.
* @return Value of the type declared in the key.
*/
@SuppressWarnings("unchecked")
public <T extends Serializable> T get(PropertyKey<T> key) {
return (T) storage.get(key);
}
/**
* Adds key/value pair to the state and returns new
* {@link PropertyHolder} with this state.
*
* @param key {@link PropertyKey} instance.
* @param value Value of type specified in {@link PropertyKey}.
* @return New {@link PropertyHolder} with updated state.
*/
public <T> PropertyHolder put(PropertyKey<T> key, T value) {
Preconditions.checkNotNull(key, "PropertyKey cannot be null");
Preconditions.checkNotNull(value, "Value for key %s is null",
key);
Preconditions.checkArgument(key.checkType(value),
"Property \"%s\" was given "
+ "value of a wrong type \"%s\"", key, value);
// Creates ImmutableMap.Builder with new key/value pair.
return new PropertyHolder(filterOutKey(key)
.put(key, value).build());
}
/**
* Returns {@link Builder} with all the elements from the state except for the given ket.
*
* @param key The key to remove.
* @return {@link Builder} for further processing.
*/
private <T> Builder<PropertyKey<? extends Serializable>, Serializable> filterOutKey(PropertyKey<T> key) {
Builder<PropertyKey<? extends Serializable>, Serializable> builder = ImmutableMap
.<PropertyKey<? extends Serializable>, Serializable> builder();
for (Entry<PropertyKey<? extends Serializable>, Serializable> entry : this.storage.entrySet()) {
if (!entry.getKey().equals(key)) {
builder.put(entry);
}
}
return builder;
}
... rest of the class
}
我在这里省略了很多不必要的细节,如果有什么不清楚,请告诉我。
I omit here a lot of unnecessary details please let me know if something is not clear.
这篇关于类似字典的数据结构。这是一个好习惯吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!