我需要创建一个静态Map
,将给定的String
映射到int
的数组。
换句话说,我想定义类似的内容:
"fred" -> {1,2,5,8}
"dave" -> {5,6,8,10,11}
"bart" -> {7,22,10010}
... etc
在Java中有一种简单的方法吗?
如果可能,我想对static
和String
值使用int
常量。
编辑:为了澄清static
常量对值的意义,并给出我认为正确的代码,这是我对解决方案的第一次尝试:< / p>
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});
}
请注意,这些名称不是我实际使用的名称。这只是一个人为的例子。
答案 0 :(得分: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});
}});
我们这里有一个带有initialization block的匿名类,它是一个在构造函数之后执行的代码块,我们在这里使用它来加载地图。
这种语法/构造有时被错误地称为“双支撑初始化” - 我想因为有两个相邻的括号 - 但实际上没有这样的东西。
关于这一点的两个很酷的事情是:
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});
}};
答案 1 :(得分:8)
您需要单独声明和初始化静态地图。
这是宣言片:
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
,但您可以添加或删除访问地图的程序其他部分的值。
答案 2 :(得分:6)
为了完整起见,因为这是google for java静态定义地图的第一个结果&#39;在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()));
这会给我们一个并发不可修改的地图。
答案 3 :(得分:1)
static Map<String, int[]> map = new HashMap<>();
地图是静态的,你可以在不创建它所定义的类的实例的情况下访问它。我不知道你的关键和值是静态的意思,因为它对我没有意义。 / p>
答案 4 :(得分: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 */
}
答案 5 :(得分:0)
您还可以使用:ImmutableMap.of(key, val)
https://guava.dev/releases/23.0/api/docs/com/google/common/collect/ImmutableMap.html#of--