可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need to create a static Map
which maps a given String
to an array of int
's.
In other words, I'd like to define something like:
"fred" -> {1,2,5,8}
"dave" -> {5,6,8,10,11}
"bart" -> {7,22,10010}
... etc
Is there an easy way to do this in Java?
And if possible, I'd like to use static
constants for both the String
and the int
values.
EDIT: To clarify what I meant by static
constants for the values, and to give what I see to be the correct code, here is my first stab at the solution:
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});
}
Note, these names are not what I'd actually be using. This is just a contrived example.
回答1:
You don't need to separate declaration and initialization. If you know how, it can all be done in one line!
// 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});
}});
What we have here is an anonymous class with an initialization block, which is a block of code that executes on construction after constructor, which we've used here to load the map.
This syntax/construct is sometimes erroneously called "double brace initialization" - I suppose because there's two adjacent braces - but there's actually no such thing.
The two cool things about this are:
- it marries the declaration with the contents, and
- because the initialization is in-line, you can also make an in-line call to
Collections.unmodifiableMap()
, resulting in a neat one-line declaration, initialization and conversion to unmodifiable.
If you don't need/want the map to be unmodifiable, leave out that call:
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:
You need to declare and initialize your static map separately.
Here is the declaration piece:
private static final Map<String,int[]> MyMap;
Here is the initialization piece:
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);
}
Unfortunately, arrays are always writable in Java. You wouldn't be able to assign MyMap
, but you would be able to add or remove values from other parts of your program that accesses the map.
回答3:
For the sake of completeness as this is the first result in google for 'java static define map' In Java 8 you can now do this.
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())));
This nice part with this is that we aren't creating anonymous classes anymore with the double brace syntax ({{ }}
)
We can then extend this with some code to clean up the pattern like this guy did here
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());
}
final result
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()));
which would give us a Concurrent Unmodifiable Map.
回答4:
static Map<String, int[]> map = new HashMap<>();
The map is static, you can access it without creating an instance of the class it's defined in. I don't know what you mean with having the keys and values static as well, because it makes no sense to me.
回答5:
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 */
}