用Java存储多键和值对的数据结构

时间:2010-11-17 04:18:38

标签: java data-structures

晚上好,

我正在寻找一种优雅的解决方案来实现转换表(特别是对于通用下推自动机),它为给定的转换使用了几个离散值。他们说一张图片胜过千言万语,所以这是我的表格的一部分:

State    InputSymbol    StackSymbol   Move(NewState, Action)
------------------------------------------------------------
  0           a              Z0           (0, push)
  0           a              a            (0, push)
  0           a              b            (0, pop)
  0           b              Z0           (1, push)
  ...

现在,我已经考虑了多维数组,ArrayLists的ArrayLists以及其他类似的解决方案,但都看起来相当野蛮。由于我的三个符号(a,b和Z0)的每个可能组合未在表中表示,因此这进一步复杂化。

我一直在考虑使用HashMap,但我不完全确定如何使用多个键值来完成此工作。我正在考虑将所有三个符号连接在一起,并使用结果字符串作为我的键,但这也似乎不太优雅。

而且,为了记录,这是家庭作业,但实际上并没有严格要求提供优雅的解决方案。我只是喜欢好的代码。

提前感谢您的协助。

3 个答案:

答案 0 :(得分:4)

制作一个这样的课程:

 class Key{
    int state;
    char inputSysmbol;
    String StackSymbol;
    }

然后使用地图Map<Key,Move>

像上面一样为Move创建一个类,不要忘记两个类中的override hashcode and equals方法。

答案 1 :(得分:1)

在对象中封装{State,InputSymbol,StackSymbol}。然后,使用对象的“hashcode()”作为哈希表的键。有关哈希码的更多信息,请参阅Doc

答案 2 :(得分:0)

从Jakarta commons集合框架看一下MultiHashMap。 http://commons.apache.org/collections/api-release/org/apache/commons/collections/MultiHashMap.html

不幸的是,jakarta集合框架没有参数化,即不支持泛型,因此您必须将特定类型转换为特定类型。

其他解决方案是实现类似你自己的东西。创建保存数据的类Move。创建封装逻辑的类表。此类可能包含Moves和N映射的列表(更好的LinkedList): 地图&GT; stateIndex 地图&GT; inputSymbolIndex 等等。

添加方法的实现是微不足道的。 get的实现更有趣:

public Move get(Integer state, Character inputSymbol, StackSymbol stackSymbol) {
    List<Move> stateList = stateIndex.get(state);
    List<Move> inputSymbolList = stateIndex.get(inputSymbol);
    List<Move> stackSymbolList = stateIndex.get(stackSymbol);

    Set<Move> result = new HashSet<Move>(stateList);
    result.retainAll(inputSymbolList);
    result.retainAll(stackSymbolList);

    if (result.size() > 1) {
        throw new IllegalStateException("Unique constraint violation");
    } 
    return  result.size() == 0 ? null : result.interator().next();
}