类似字典的数据结构。这是一个好的做法吗?

2024-02-03

我需要一个数据结构来存储不同类型的对象。String, Boolean和其他课程。
正在使用一个Map<String, Object>在哪里使用密钥可以获得相应的对象,假设您知道如何将其转换为良好的实践?
有更好的解决方案吗?


这是一个完美的用例PropretyHolder我不久前写过。您可以阅读有关它的详细内容my blog http://koblik.blogspot.ch/2012/09/keyvalue-in-memory-storage-for-java.html。我开发它时考虑到了不变性,请随意调整它以满足您的需求。

一般来说,我想说如果你想从 Java 中的类型安全中获益,你需要知道你的密钥。我的意思是 - 几乎不可能开发密钥来自外部源的类型安全解决方案。


这是一个特殊的键,它知道其值的类型(它不完整,请下载源代码 https://sites.google.com/site/ivankoblik/web-storage/KVStore.zip完整版本):

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

}

然后您开发一个利用它的数据结构:

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

}

我在这里省略了很多不必要的细节,如果有不清楚的地方请告诉我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类似字典的数据结构。这是一个好的做法吗? 的相关文章

随机推荐