如何创建一个静态Map of String - > Array

Dun*_*ear 13 java static map

我需要创建一个静态Map,将给定String的数组映射到int.

换句话说,我想定义类似的东西:

"fred" -> {1,2,5,8}
"dave" -> {5,6,8,10,11}
"bart" -> {7,22,10010}
... etc
Run Code Online (Sandbox Code Playgroud)

在Java中有一种简单的方法吗?

如果可能的话,我想对static常量Stringint值使用常量.

编辑:为了阐明我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});
}
Run Code Online (Sandbox Code Playgroud)

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

Boh*_*ian 29

并不需要单独的声明和初始化.如果你知道如何,它可以在一行中完成!

// 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});
    }});
Run Code Online (Sandbox Code Playgroud)

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

这种语法/构造有时被错误地称为"双支撑初始化" - 我想因为有两个相邻的括号 - 但实际上没有这样的东西.

关于这个的两个很酷的事情是:

  • 它将声明与内容结合,并且
  • 因为初始化是内联的,你也可以进行内联调用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});
}};
Run Code Online (Sandbox Code Playgroud)


das*_*ght 8

您需要单独声明和初始化静态地图.

这是宣言片:

private static final Map<String,int[]> MyMap;
Run Code Online (Sandbox Code Playgroud)

这是初始化部分:

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);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,数组总是可以用Java编写的.您将无法分配MyMap,但您可以在程序的其他访问地图的部分中添加或删除值.

  • @Bohemian很好的借口可以回答竞争的答案;-)我想指出"需要"和"必须"不是*同一件事.此外,在Java 5之前还没有双支撑替代方案. (2认同)

xor*_*ori 6

为了完整起见,因为这是google中"java静态定义映射"的第一个结果.在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())));
Run Code Online (Sandbox Code Playgroud)

这个很好的部分是我们不再使用双括号语法创建匿名类({{ }})

然后我们可以用一些代码扩展这个来清理模式,就像这个人在这里做的那样 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());
}
Run Code Online (Sandbox Code Playgroud)

最后结果

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()));
Run Code Online (Sandbox Code Playgroud)

这将给我们一个并发不可修改的地图.