1

考虑以下情况:

我有一个以 String 为键的映射,另一个 Map 作为值。现在value中的Map也是一个以String为key、以Map为value的Map。我们有这样的 n 个级别,最后一个级别有一个 Map,其中 String 为键,String 为值。现在假设,我有每个级别的键列表。我必须得到最终的字符串值。

这就是我想在java中实现它的方式:

Object q = initialMap; 
for(String key : keyList)
{
    Map x = (Map)q;
    q = x.get(key);
}
return (String)q;

这是处理这个问题的正确方法吗?我收到了未经检查的转换警告。有没有更好的方法来做到这一点?

4

1 回答 1

1

我想我理解你的问题,你从一个文件中获得一个字符串映射到字符串映射到......等等的映射。这样的事情:

 Map<String, Map<String, Map<String, Map<String, String>>>> initialMap;

您的问题中不清楚的是您是否知道会有多少级别的地图。如果是,那么只需像我刚刚所做的那样(对于 4 个级别的地图)编写您需要的级别数的 initialMap。

如果你事先不知道你有多少级别,那就更难了。在这种情况下,您的算法是合理的。我只会让它更像这样的泛型:

Object q = initialMap; 
for(String key : keyList)
{
    Map<String, ?> x = (Map<String, ?>)q;
    q = x.get(key);
}
return (String)q;

但这总是会给你一个警告,你必须通过在方法中添加 @SuppressWarnings("unchecked") 来抑制。

您可以尝试在方法中将其抽象出来。

编辑:有一种方法可以在实用程序类中完全抽象它。我会称你想要一种递归地图。您的任何 Map 要么是从 String 到 String 的映射,要么是从 String 到递归映射的映射。这可以这样抽象:

interface IRecursiveMap {
  String get(List<String> keyList);
}

class RecursiveMap implements IRecursiveMap{
  Map<String, IRecursiveMap> map;

  @Override
  public String get(List<String> keyList) {
    String key = keyList.get(0);
    return map.get(key).get(keyList.subList(1, keyList.size()));
  }
}

class ValueMap implements IRecursiveMap{
  Map<String, String> map;

  @Override
  public String get(List<String> keyList) {
    String key = keyList.get(0);
    return map.get(key);
  }
}

因此 IRecursiveMap 是定义映射的常见行为的接口:从键列表中获取某些内容的能力。RecursiveMap 是将一个 String 映射到另一个 IRecursiveMap 的实现,而 ValueMap 是递归的最后一个映射,它实际上将 String 映射到 String。

该实施的好处是:

  • 代码正确使用泛型并且数据是完全类型化的。这意味着您没有更多通用警告。
  • 在这个映射链中存储东西的所有逻辑都抽象在几个实用程序类中。

另一方面,缺点是填充地图可能有点复杂,但同样可以递归完成。

于 2013-03-08T18:40:14.090 回答