【问题标题】:how to easily access nested maps in java(or google guava)如何在 java(或 google guava)中轻松访问嵌套地图
【发布时间】:2014-05-08 23:19:17
【问题描述】:

我有一个嵌套的 Hashmap(使用 JDK 7),定义如下

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

所有映射的所有键(也嵌套)在运行时创建,外部映射的值是另一个映射;下一级地图的值是另一个地图;而最内层map的值只是一个Double(它不会是collection)。

我使用上述数据结构来维护缓存(树状对象层次结构),其中最内层映射的值每秒更新一次(即 Double 类型)。

我在寻找更好/更简单的嵌套地图时遇到了http://tomjefferys.blogspot.com/2011/09/multimaps-google-guava.html。但是最内层地图的价值永远不会是收藏,所以谷歌番石榴乍一看似乎没有相关性(?)

我也遇到了这个How to iterate through Nested Map and Multiset? - Java/Guava,甚至在番石榴中迭代也没有更好(似乎)。

在迭代或更新我的场景的值(地图中的地图中的地图)时,我试图减少常规(肉鸡板)代码,以及如何重写我现有的代码以切换到 Google Guava 的多地图(或者将比 jdk7 的常规哈希图更好)。

****编辑**** 我同意有这么深的嵌套是不寻常的。我可以有一个地图列表,但是查找会很昂贵。这是地图的细分

HashMap : 外层映射表示各种数据源作为键(例如:NDAQ、CBOE、NYSE、AMEX)

HashMap 中级映射表示各种代码作为键(例如:CSCO,INTC,MSFT..)

HashMap:外层map表示各种统计参数的值(EX:mean,median,skew,kurtosis)作为key,就是这些Double值 每分钟更新一次

注意:以上 3 个映射中的所有键都是预先知道的(因此映射在运行时不会增长或调整大小 - 它只是最内部映射中的 Double 值,每分钟更新一次)

【问题讨论】:

标签: java collections guava apache-commons


【解决方案1】:

Guava Table 可以帮助您解决问题吗?

归根结底,需要有这么多间接的问题是不寻常的。你想在这个结构中表示什么样的数据?您要执行哪些类型的操作?

【讨论】:

  • 更新了我为什么需要这个数据结构的帖子。我需要间接以便更容易查找。不确定这是否是天生的异常问题(或我的设计)
【解决方案2】:

令我震惊的是,您正在使用集合类型来代替适当的复杂键。

如果我可以总结一下您要完成的工作,那就是根据三件事查找股票统计数据:提要、股票代码和统计类型。在我看来,这个HashMap 结构仅用于缓存和查找,而层次结构在其他方面并不相关。

鉴于此,让我们定义一个复杂的键:

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);
    }
}

现在您可以拥有一个Cache&lt;StockStatisticKey, Double&gt;,您可以在其中根据这个复杂的键快速查找您的值。这应该像嵌套的 HashMap 一样执行每一位,并为其添加语义值。

您也可以考虑这种情况的一些变体,其中SourceSystemIdEnum 和股票名称一起形成一个键,StatusEnum 作为第二个键,这些值将进入 Guava Table

【讨论】:

  • 有趣的观察使我无法理解。但是,我将无法访问特定的分支;例如:获取特定股票代码/INTC 的所有统计信息;或者让我获得数据馈送/纽约证券交易所所有股票代码的所有统计信息 - 我使用这些场景在仪表板中显示一组值
  • 你可以用 Guava AutoValue 简化代码?
【解决方案3】:

Trees 似乎是一个很好的数据结构(正如@Ata 建议的那样)。因为没有标准的 JDK 实现树(??)并且不相信添加开源树实现(来自 maven),所以我将坚持使用现有的嵌套映射。 如果我找到更好的解决方案,我会更新这个答案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2012-05-31
    相关资源
    最近更新 更多