如何创建字符串 -> 数组的静态映射

2022-09-04 05:22:47

我需要创建一个静态的,它将给定映射到一个数组的' 。MapStringint

换句话说,我想定义如下内容:

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

有没有一种简单的方法可以在Java中做到这一点?

如果可能的话,我想对 值和值都使用常量。staticStringint

编辑:为了澄清我对值的常量的含义,并给出我认为是正确的代码,这是我第一次尝试解决方案: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});
}

请注意,这些名称不是我实际使用的名称。这只是一个人为的例子。


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

我们在这里有一个带有初始化块的匿名类,它是一个在构造函数之后的构造上执行的代码块,我们在这里使用它来加载映射。

这种语法/构造有时被错误地称为“双大括号初始化” - 我想是因为有两个相邻的大括号 - 但实际上没有这样的事情。

关于这一点的两件很酷的事情是:

  • 它将声明与内容相结合,并且
  • 因为初始化是内联的,所以还可以对 进行内联调用,从而产生整洁的单行声明,初始化并转换为不可修改。Collections.unmodifiableMap()

如果您不需要/不希望地图不可修改,请省略该调用:

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

答案 2

您需要单独声明和初始化静态映射。

这是宣言部分:

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


推荐