Gibt es eine Möglichkeit, eine Java HashMap wie folgt zu initialisieren ?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
Was wäre die richtige Syntax? Ich habe dazu nichts gefunden. Ist das möglich? Ich suche nach dem kürzesten/schnellsten Weg, um einige "endgültige/statische" Werte in eine Karte einzufügen, die sich nie ändern und die beim Erstellen der Karte im Voraus bekannt sind.
Ja, das ist jetzt möglich. In Java 9 wurden einige Factory-Methoden hinzugefügt, die die Erstellung von Maps vereinfachen:
// this works for up to 10 elements:
Map<String, String> test1 = Map.of(
"a", "b",
"c", "d"
);
// this works for any number of elements:
Map<String, String> test2 = Map.ofEntries(
entry("a", "b"),
entry("c", "d")
);
Im obigen Beispiel sind sowohl test
als auch test2
gleich, nur mit unterschiedlichen Arten, die Map auszudrücken. Die Map.of
-Methode ist für bis zu zehn Elemente in der Map definiert, während die Map.ofEntries
-Methode keine solche Begrenzung hat.
Beachten Sie, dass die resultierende Karte in diesem Fall eine unveränderliche Karte ist. Wenn Sie möchten, dass die Karte veränderbar ist, können Sie sie erneut kopieren, z. mit mutableMap = new HashMap<>(Map.of("a", "b"));
(Siehe auch JEP 269 und Javadoc )
Nein, Sie müssen alle Elemente manuell hinzufügen. Sie können einen Initialisierer in einer anonymen Unterklasse verwenden, um die Syntax ein wenig zu verkürzen:
Map<String, String> myMap = new HashMap<>() {{
put("a", "b");
put("c", "d");
}};
In einigen Fällen kann die anonyme Unterklasse jedoch zu unerwünschtem Verhalten führen. Dies beinhaltet zum Beispiel:
Die Verwendung einer Funktion zur Initialisierung ermöglicht es Ihnen auch, eine Karte in einem Initialisierer zu generieren, vermeidet jedoch böse Nebenwirkungen:
Map<String, String> myMap = createMap();
private static Map<String, String> createMap() {
Map<String,String> myMap = new HashMap<String,String>();
myMap.put("a", "b");
myMap.put("c", "d");
return myMap;
}
Das ist eine Möglichkeit.
HashMap<String, String> h = new HashMap<String, String>() {{
put("a","b");
}};
Sie sollten jedoch vorsichtig sein und sicherstellen, dass Sie den obigen Code verstehen (er erstellt eine neue Klasse, die von HashMap erbt). Lesen Sie daher hier mehr: http://www.c2.com/cgi/wiki?DoubleBraceInitialization oder verwenden Sie einfach Guava:
Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
Wenn Sie Drittanbieter-Bibliotheken zulassen, können Sie Guava 's ImmutableMap verwenden, um eine buchstäbliche Kürze zu erzielen:
Map<String, String> test = ImmutableMap.of("k1", "v1", "k2", "v2");
Dies funktioniert für bis zu 5 Schlüssel/Wert-Paare , ansonsten können Sie sein Builder verwenden:
Map<String, String> test = ImmutableMap.<String, String>builder()
.put("k1", "v1")
.put("k2", "v2")
...
.build();
Es gibt keine direkte Möglichkeit, dies zu tun - Java hat keine Map-Literale (noch - ich denke, sie wurden für Java 8 vorgeschlagen).
Einige Leute mögen das:
Map<String,String> test = new HashMap<String, String>(){{
put("test","test"); put("test","test");}};
Dadurch wird eine anonyme Unterklasse von HashMap erstellt, deren Instanzinitialisierer diese Werte festlegt. (Übrigens kann eine Map nicht zweimal den gleichen Wert enthalten, Ihr zweiter Put überschreibt den ersten. Für die nächsten Beispiele verwende ich andere Werte.)
Der normale Weg wäre (für eine lokale Variable):
Map<String,String> test = new HashMap<String, String>();
test.put("test","test");
test.put("test1","test2");
Wenn Ihre test
-Map eine Instanzvariable ist, fügen Sie die Initialisierung in einen Konstruktor oder einen Instanzinitialisierer ein:
Map<String,String> test = new HashMap<String, String>();
{
test.put("test","test");
test.put("test1","test2");
}
Wenn Ihre test
Map eine Klassenvariable ist, platzieren Sie die Initialisierung in einem statischen Initialisierer:
static Map<String,String> test = new HashMap<String, String>();
static {
test.put("test","test");
test.put("test1","test2");
}
Wenn Sie möchten, dass sich Ihre Map niemals ändert, sollten Sie Ihre Map nach der Initialisierung mit Collections.unmodifiableMap(...)
umschließen. Sie können dies auch in einem statischen Initialisierer tun:
static Map<String,String> test;
{
Map<String,String> temp = new HashMap<String, String>();
temp.put("test","test");
temp.put("test1","test2");
test = Collections.unmodifiableMap(temp);
}
(Ich bin nicht sicher, ob Sie jetzt test
final machen können ... probieren Sie es aus und berichten Sie hier.)
Map<String,String> test = new HashMap<String, String>()
{
{
put(key1, value1);
put(key2, value2);
}
};
Eine Alternative mit einfachen Java 7-Klassen und -Varargen: Erstellen Sie eine Klasse HashMapBuilder
mit dieser Methode:
public static HashMap<String, String> build(String... data){
HashMap<String, String> result = new HashMap<String, String>();
if(data.length % 2 != 0)
throw new IllegalArgumentException("Odd number of arguments");
String key = null;
Integer step = -1;
for(String value : data){
step++;
switch(step % 2){
case 0:
if(value == null)
throw new IllegalArgumentException("Null key value");
key = value;
continue;
case 1:
result.put(key, value);
break;
}
}
return result;
}
Verwenden Sie die Methode wie folgt:
HashMap<String,String> data = HashMapBuilder.build("key1","value1","key2","value2");