2012-11-18 7 views
10

Stringintの配列にマップする静的Mapを作成する必要があります。言い換えればString - > Arrayの静的マップを作成する方法

、私は次のように定義したいと思います:

"fred" -> {1,2,5,8} 
"dave" -> {5,6,8,10,11} 
"bart" -> {7,22,10010} 
... etc 

は、Javaでこれを行う簡単な方法はありますか?

可能であれば、Stringintの両方の値には、staticの定数を使用したいと思います。

EDIT:私は値のためstatic定数によって何を意味するのか明確にするために、私は正しいコードであることを見るもの与えることを、ここに解決策で私の最初の刺し傷である:

public final static String FRED_TEXT = "fred"; 
public final static String DAVE_TEXT = "dave"; 

public final static int ONE = 1; 
public final static int TWO = 2; 
public final static int THREE = 3; 
public final static int FOUR = 4; 

public final static HashMap<String, int[]> myMap = new HashMap<String, int[]>(); 
static { 
    myMap.put(FRED_TEXT, new int[] {ONE, TWO, FOUR}); 
    myMap.put(DAVE_TEXT, new int[] {TWO, THREE}); 
} 

注意、これらの名前は私が実際に使っているものではありません。これは単なる人為的な例です。

答えて

21

は、宣言と初期化を分ける必要がありません。あなたがどのように知っていれば、それはすべて1行で行うことができます!

// assumes your code declaring the constants ONE, FRED_TEXT etc is before this line 
private static final Map<String, int[]> myMap = Collections.unmodifiableMap(
    new HashMap<String, int[]>() {{ 
     put(FRED_TEXT, new int[] {ONE, TWO, FOUR}); 
     put(DAVE_TEXT, new int[] {TWO, THREE}); 
    }}); 

私たちがここに持っていることはinialization blockと匿名クラスである - 私たちはマップをロードするために、ここで使用しましたコンストラクタの後に建設上で実行されるコードのブロックは、(これは時々誤って二重ブレース」として知られています初期化 " - 2つの隣接する中括弧が存在するためですが、実際にはそのようなものはありません)。

この2つの素晴らしい点は、a)宣言が内容と結びついていること、b)初期化がインラインであるため、Collections.unmodifiableMap()をインラインで呼び出して、宣言、初期化、および変更不可能なものへの変換。

あなたは/マップは変更不可能になりたい必要がない場合、そのコールアウトのまま:これは「Javaの静的のためのGoogleの最初の結果であるとして、完全を期すために

private static final Map<String, int[]> myMap = new HashMap<String, int[]>() {{ 
    put(FRED_TEXT, new int[] {ONE, TWO, FOUR}); 
    put(DAVE_TEXT, new int[] {TWO, THREE}); 
}}; 
+0

ああ、私はスーパークラスでマップを宣言する必要がありますが、サブクラスでそれを設定します。申し訳ありませんが、私はこれが私の元の質問にはなかったことを知っています。私はまだ 'static'ブロックが必要でしょうか? – DuncanKinnear

+0

しかし、これは 'static'なので、「コンストラクタの後に構築時に実行されるコードブロック」とはどのようになりますか?静的なコードを参照するときには構造が発生しないと思っていました。 – DuncanKinnear

+1

@DuncanKinnearインスタンスは静的ですが、ブロックはありません。ブロックは静的にインスタンス化されている匿名クラスのインスタンスブロックです。匿名クラスは 'HashMap'のサブクラスです。インスタンスは1つしか存在しません(' new'は一度だけ呼び出されます)。 – Bohemian

1
static Map<String, int[]> map = new HashMap<>(); 

マップは、あなたはそれがで定義されていたクラスのインスタンスを作成せずにアクセスすることができ、静的である。それは意味がありませんので、私は、あなたが鍵を有するだけでなく、静的な値で何を意味するのか分かりません私に。

+0

静的定数を使用する例については、私の編集をご覧ください。 – DuncanKinnear

5

スタティックマップを個別に宣言して初期化する必要があります。ここで

が宣言ピースである:ここで

private static final Map<String,int[]> MyMap; 

が初期化ピースである:

static { 
    Map<String,int[]> tmpMap = new HashMap<String,int[]>(); 
    tmpMap.put("fred", new int[] {1,2,5,8}); 
    tmpMap.put("dave", new int[] {5,6,8,10,11}); 
    tmpMap.put("bart", new int[] {7,22,10010}); 
    MyMap = Collections.unmodifiableMap(tmpMap); 
} 

残念ながら、配列はJavaで常に書き込み可能です。 MyMapを割り当てることはできませんが、マップにアクセスするプログラムの他の部分から値を追加または削除することは可能です。

+1

+1静的イニシャライザブロック – jlordo

+1

もちろん、この例ではマップと配列の両方が書き込み可能です。 – cdhowie

+0

@cdhowieあなたが正しいです、私はこのポイントを強調するために答えに段落を追加しました。 – dasblinkenlight

0
public class ExampleClass { 
    public final static HashMap consts = new HashMap(); 
    static 
    { 
     constants.put("A", "The Letter A"); 
     constants.put("B", "The Letter B"); 
     constants.put("C", "The Letter C"); 
    } 
    /* Rest of your class that needs to know the consts */ 
} 
+0

私は間違っているが、 "consts"初期化の前に静的ブロックが実行されている場合は私を訂正しますか? –

+0

私はテストして、あなたが書いたものはすべて正しいものです。しかし、もし私たちがconstの初期化ブロックと静的ブロックを切り替えると、コンパイルエラーが発生します。要素を定義する順序がJavaでは何の効果もないとは思っていませんでした。 –

5

は、 Java 8ではこれを行うことができます。

Collections.unmodifiableMap(Stream.of(
      new SimpleEntry<>("a", new int[]{1,2,3}), 
      new SimpleEntry<>("b", new int[]{1,2,3}), 
      new SimpleEntry<>("c", new int[]{1,2,3})) 
      .collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue()))); 

これでこの素敵な部分は、我々は、この男のようなパターンをクリーンアップするためにいくつかのコードでこれを拡張することができます({{ }}

ダブルブレースの構文でもう匿名クラスを作成していないということですここでやった http://minborgsjavapot.blogspot.ca/2014/12/java-8-initializing-maps-in-smartest-way.html

public static <K, V> Map.Entry<K, V> entry(K key, V value) { 
    return new AbstractMap.SimpleEntry<>(key, value); 
} 

public static <K, U> Collector<Map.Entry<K, U>, ?, Map<K, U>> entriesToMap() { 
    return Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue()); 
} 

public static <K, U> Collector<Map.Entry<K, U>, ?, ConcurrentMap<K, U>> entriesToConcurrentMap() { 
    return Collectors.toConcurrentMap((e) -> e.getKey(), (e) -> e.getValue()); 
} 

最終結果

Collections.unmodifiableMap(Stream.of(
      entry("a", new int[]{1,2,3}), 
      entry("b", new int[]{1,2,3}), 
      entry("c", new int[]{1,2,3})) 
      .collect(entriesToMap())); 

これは、同時変更不可能なマップを提供します。

+0

答えをありがとう。私たちはJava 6についています。 – DuncanKinnear

関連する問題