简体   繁体   English

如何轻松访问Java(或Google番石榴)中的嵌套地图

[英]how to easily access nested maps in java(or google guava)

I have a nested Hashmap (using JDK 7) as defined below 我有一个嵌套的Hashmap(使用JDK 7),如下所示

private static HashMap<SourceSystemIdEnum, HashMap<String, HashMap<StatsEnum, Double>>> statsCache = new HashMap<SourceSystemIdEnum, HashMap<String, HashMap<StatsEnum, Double>>>();

All the keys for all the maps (nested as well) are created at runtime and the value of outer map is another map; 所有映射的所有键(以及嵌套的)都是在运行时创建的,外部映射的值是另一个映射。 the values of next level of map is another map; 下一地图的值是另一地图; and the value of inner most map is just a Double (it is not going to be collection). 而最里面的地图的值只是Double(不会被收集)。

I use above data structure to maintain cache (tree like object hierarchy) where the values of inner most map is updated every second (that is Double type). 我使用上述数据结构来维护高速缓存(树状的对象层次结构),其中最里面的映射的值每秒更新一次(即Double类型)。

I came across http://tomjefferys.blogspot.com/2011/09/multimaps-google-guava.html , while looking for a better/easier nested maps. 我在寻找更好/更轻松的嵌套地图时遇到了http://tomjefferys.blogspot.com/2011/09/multimaps-google-guava.html But the value of inner most map is never going to be collection, so google Guava didnt seem relevant at first look(?) 但是,最里面的地图的价值永远不会被收集,因此google Guava乍一看似乎并不相关(?)

I also came across this How to iterate through Nested Map and Multiset? 我还遇到了如何遍历嵌套地图和多集? - Java/Guava and even iteration doesnt be any better in guava (it seems). -Java / Guava ,甚至迭代在guava中也没有任何改善(似乎)。

I am trying to reduce routine (broiler plate) code when iterating or updating the values of my scenario (map within map within map) and how can I rewrite my existing code to switch to Google Guava's multimap (or is that going to be any better than regular hashmap of jdk7 ). 我在尝试迭代或更新场景(地图中地图内的地图)的值时,尝试减少常规代码(烧烤盘),以及如何重写现有代码以切换到Google Guava的多地图(或者会变得更好)比jdk7的常规哈希图)。

****EDIT**** I agree it is unusual to have such deep nesting. ****编辑****我同意有这么深的嵌套是不寻常的。 I can have a list of maps, but then lookup is going to be costly. 我可以有一张地图列表,但是查找会很昂贵。 Here is the breakdown of maps 这是地图的细分

HashMap : the outer map represents various data feeds as the keys(ex:NDAQ,CBOE,NYSE,AMEX) HashMap:外部地图将各种数据提要表示为键(例如:NDAQ,CBOE,NYSE,AMEX)

HashMap the mid level map represents various tickers as the keys(ex:CSCO,INTC,MSFT..) HashMap中级地图将各种股票代号表示为键(例如:CSCO,INTC,MSFT ..)

HashMap: the outer map represents values of various statistical parameters (EX: mean, median, skew,kurtosis) as the keys and it is these Double values that get updated every minute HashMap:外部图表示各种统计参数(例如:平均值,中位数,偏斜,峰度)的值作为键,并且这些Double值每分钟都会更新

NOTE: All the keys in above 3 maps are pretty much known in advance (so maps dont grow or resize during runtime-it is only Double value in inner most map that gets updated every minute) 注意:以上3个映射中的所有键都是事先已知的(因此,映射在运行时不会增长或调整大小,它只是最里面的映射中的Double值,每分钟都会更新)

Could a Guava Table help with your problem? 番石榴Table可以解决您的问题吗?

Ultimately, it's unusual to have a problem where you need to have so many indirections. 最终,遇到需要很多间接访问的问题是不寻常的。 What kind of data are you trying to represent in this structure? 您要在这种结构中表示什么样的数据? What kinds of operations are you trying to perform? 您要执行哪种操作?

It strikes me that you are using collection types as a substitute for a proper complex key. 令我惊讶的是,您正在使用集合类型代替适当的复杂键。

If I can boil down what you're trying to accomplish, it is to look up a stock statistic based on three things: the feed, ticker, and statistic type. 如果我可以归纳出您要完成的工作,那就是根据以下三点来查找库存统计信息:提要,报价器和统计信息类型。 It seems to me that this HashMap structure is being used simply for caching and lookups, and that the hierarchy is not otherwise relevant. 在我看来,此HashMap结构仅用于缓存和查找,而层次结构在其他方面不相关。

Given that, let's define a complex key: 鉴于此,让我们定义一个复杂的键:

public final class StockStatisticKey {
    private final SourceSystemIdEnum systemId;
    private final String tickerName;
    private final StatsEnum statType;

    public StockStatisticKey(SourceSystemIdEnum systemId, String tickerName, StatsEnum statType) {
            this.systemId = systemId;
            this.tickerName = tickerName;
            this.statType = statType;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof StockStatisticKey) {
            StockStatisticKey other = (StockStatisticKey) obj;
            boolean equal = true;
            equal &= Objects.equal(systemId, other.systemId);
            equal &= Objects.equal(tickerName, other.tickerName);
            equal &= Objects.equal(statType, other.statType);

            return equal;
        }

        return false;
    }

    public int hashCode() {
        return Objects.hashCode(systemId, tickerName, statType);
    }
}

Now you can have a Cache<StockStatisticKey, Double> where you can very quickly look up your value based on this complex key. 现在您可以拥有Cache<StockStatisticKey, Double> ,您可以在其中基于此复杂键快速查找您的值。 This should perform every bit as well as your nested HashMaps, and adds to it semantic value. 这应该像嵌套HashMaps一样执行所有操作,并为其添加语义值。

You may also consider some variant of this, where the SourceSystemIdEnum and the ticker name together form one key, the StatusEnum as second key, and these values would go into a Guava Table . 您还可以考虑这样做的一些变体,其中SourceSystemIdEnum和代码名称一起构成一个键, StatusEnum作为第二个键,并且这些值将进入Guava Table

It seems Trees is good data structure (as @Ata suggested). 看来Trees是很好的数据结构(如@Ata所建议)。 Because there is no standard JDK implementation of tree(??) and not convinced with adding open source tree implementations (from maven), I am going to stick with my existing nested maps. 因为没有树(??)的标准JDK实现,并且不确信要添加开源树实现(来自Maven),所以我将坚持使用现有的嵌套映射。 I will update this answer, if I find better solution 如果我找到更好的解决方案,我将更新此答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM