13

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

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

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

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

如果可能的话,我想对 the和值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});
}

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

4

6 回答 6

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

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

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

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

  • 它将声明与内容结合起来,并且
  • 因为初始化是内联的,您也可以对 进行内联调用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});
}};
于 2012-11-19T01:25:12.103 回答
9

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

这是声明部分:

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,但您将能够从访问地图的程序的其他部分添加或删除值。

于 2012-11-18T23:28:02.253 回答
6

为了完整起见,因为这是 google 中“java static define map”的第一个结果,在 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()));

这会给我们一个并发不可修改的地图。

于 2015-02-10T19:12:41.020 回答
1
static Map<String, int[]> map = new HashMap<>();

该映射是静态的,您可以在不创建它定义的类的实例的情况下访问它。我不知道您的键和值也静态是什么意思,因为这对我来说毫无意义。

于 2012-11-18T23:27:02.560 回答
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 */
}
于 2014-09-09T16:07:43.557 回答
0

您还可以使用:ImmutableMap.of(key, val)

https://guava.dev/releases/23.0/api/docs/com/google/common/collect/ImmutableMap.html#of--

于 2020-07-13T22:39:49.107 回答