1

次の状況を考慮してください。

String をキーとし、別の Map を値とするマップがあります。現在、値のマップは、文字列をキーとして、マップを値として持つマップでもあります。このような n レベルがいくつかあり、最終レベルには String をキーとして、String を値として持つ Map があります。ここで、各レベルのキーのリストがあるとします。最終的な文字列値を取得する必要があります。

これは私がJavaでそれを実装することを考えた方法です:

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

これはこれにアプローチする正しい方法ですか?これで未チェックの変換警告が表示されます。これを行うより良い方法はありますか?

4

1 に答える 1

1

私はあなたの問題を理解していると思います.ファイルからMap of String to Map of String to Map of ...などを取得します.

 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 に答える