it-swarm.com.de

Kann ich in Java eine HashMap-Konstante deklarieren?

Ich schreibe ein einfaches Programm, um eine Zahl in ein Word umzuwandeln, das diese Zahl darstellt (13 => "dreizehn"). 

Mir ist klar, dass ich einige der Wörter mit einem konstanten String-Array wie folgt erhalten konnte: 

private static final String[] tensNames = {"", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" };

... und mit dem Index darauf zugreifen, aber ich wollte es mit einer HashMap wie folgt versuchen: 

final HashMap<Integer, String> tensNumberConversion = new HashMap<Integer, String>();
    tensNumberConversion.put(2, "twenty");
    tensNumberConversion.put(3, "thirty");
    tensNumberConversion.put(4, "forty");
    tensNumberConversion.put(5, "fifty");
    tensNumberConversion.put(6, "sixty");
    tensNumberConversion.put(7, "seventy");
    tensNumberConversion.put(8, "eighty");
    tensNumberConversion.put(9, "ninety");

Ich wurde von einem Lehrer angewiesen, diese Konstanten zu erstellen. Kann die HashMap eine Konstante sein? Als Neuling war nicht völlig klar, wie die Begriffe "konstant" und "statisch" und "endgültig" zusammenhängen und was genau eine Konstante ist. (statisch allein - Finale allein - statisches Finale zusammen?).

Ich habe versucht, es als private statische Hashmap zu erstellen, aber IntelliJ gab mir einen Fehler (Modifikator 'private' ist hier nicht zulässig ... dasselbe für 'static'). 

Es wird jedoch von meinem Terminal ohne Fehler kompiliert. Wenn eine HashMap eine Konstante sein kann, ist dies der richtige Weg, eine zu deklarieren? Vielen Dank!

8
Hoonta

Hier gibt es zwei Aspekte:

  • Sie haben eine Variable, die einen Verweis auf eine Karte enthält. Sie erklären einfach, dass diese Variable final ist. und voilà, Sie können die Variable nicht so ändern, dass sie auf eine andere - Referenz verweist.
  • Das hindert Sie jedoch nicht daran, den state des Objekts zu ändern, auf das der Verweis zeigt. Selbst wenn Sie ein final Map -Objekt haben, können Sie die put/remove/... -Methoden auf dieser Map aufrufen.

Um zu einer echten "konstanten" Karte zu gelangen, müssen Sie Folgendes tun:

Zuerst erstellen Sie eine gewöhnliche Karte, die alle gewünschten Werte enthält. 

Dann verwenden Sie Collections.unmodifiableMap(), um eine Karte zu erstellen, die nicht mehr geändert werden kann. 

Die einzige Sache, auf die Sie achten müssen: Sie müssen sicherstellen, dass Sie keinen Verweis auf das ursprüngliche Kartenobjekt verlieren, da diese unveränderliche Karte nur eine Hülle um die ursprüngliche Karte ist. Das können Sie zum Beispiel in einer kleinen Hilfsmethode tun. 

Wenn Sie fragen: Gibt es eine Möglichkeit, eine Kartendeklaration in einer speziellen "wörtlichen Form" (wie bei Arrays) aufzuschreiben - gibt es nicht. Nun, Sie können diese Hilfsmethode ändern, um Object ... als Parameter zu übernehmen. und dann würden Sie diese Parameter durchgehen, einer ist eine Zahl, der nächste eine Zeichenfolge und verwendet diese, um die Karte zu füllen. Sie können die Methode dann mit einer einzelnen Folge von Werten aufrufen. Aber die Mühe wahrscheinlich nicht wert ...

Ein kurzes Update: Java9 fügte verschiedene statische Hilfsmethoden hinzu, mit denen Sie Karten irgendwie "wörtlich" aufschreiben können, siehe zum Beispiel hier .

11
GhostCat

Ja, es kann eine Konstante sein. Sie sollten Ihre HashMap-Instanz wie folgt deklarieren:

class <class name> {
    private static final HashMap<Integer, String> tensNumberConversion = new HashMap<>();

    static {
        tensNumberConversion.put(2, "twenty");
        tensNumberConversion.put(3, "thirty");
        tensNumberConversion.put(4, "forty");
        tensNumberConversion.put(5, "fifty");
        tensNumberConversion.put(6, "sixty");
        tensNumberConversion.put(7, "seventy");
        tensNumberConversion.put(8, "eighty");
        tensNumberConversion.put(9, "ninety");
    }
}

Dies ist jedoch nur eine konstante Referenz. Sie können zwar tensNumberConversion nicht zu einem anderen Objekt zuweisen, Sie können den Inhalt Ihrer Map jedoch später noch zur Laufzeit ändern:

tensNumberConversion = new HashMap<>(); // won't compile
tensNumberConversion.put(9, "one"); // succeeds

Wenn Sie möchten, dass auch der Inhalt Ihrer Karte konstant bleibt, müssen Sie die Variable HashMap in eine unveränderbare Karte einschließen:

class <class name> {
    private static final Map<Integer, String> tensNumberConversion = initMap();

    private static Map<Integer, String> initMap() {
        Map<Integer, String> map = new HashMap<>();
        map.put(2, "twenty");
        map.put(3, "thirty");
        map.put(4, "forty");
        map.put(5, "fifty");
        map.put(6, "sixty");
        map.put(7, "seventy");
        map.put(8, "eighty");
        map.put(9, "ninety");
        return Collections.unmodifiableMap(map);
    }
}
15
ZhekaKozlov

Nur ein BTW, mit Java 9 gibt es statische Methoden in der Map-Schnittstelle , um unveränderliche Maps mit einigen Einträgen zu erstellen, wie zum Beispiel:

Map<String,String> m = Map.of("k1", "v1",
                              "K2", "v2");

Oder wenn mehr als 10 Einträge benötigt werden:

import static Java.util.Map.entry;
Map<String, String> m = Map.ofEntries(
    entry("k1", "v1"), entry("k2", "v2"), …);
6
eckes

Ich habe die einfachste Form für die direkte Initialisierung der HashMap hier irgendwie vermisst

private static final Map<Integer, String> tensNumberConversion_internal = new HashMap<Integer, String>()
{
    {
        put(2, "twenty");
        put(3, "thirty");
        put(4, "forty");
        put(5, "fifty");
        put(6, "sixty");
        put(7, "seventy");
        put(8, "eighty");
        put(9, "ninety");
    };
};

und um es unveränderlich zu machen, haben Sie Collections.unmodifiableMap bereits von der akzeptierten Antwort so

public static final Map<Integer, String> tensNumberConversion = Collections.unmodifiableMap(tensNumberConversion_internal);

sie müssen in dieser Reihenfolge erstellt werden;)

1
derHugo

Anstatt Kompostierung zu verwenden, um eine konstante HashMap zu erhalten, können Sie Vererbung verwenden, um eine neue Klasse von HashMap zu erben, und dann die HashMap.put () -Methode überschreiben, um eine entsprechende Fehlermeldung anzuzeigen.

class MyMap extends Java.util.HashMap{
@Override
public V put (K key, V value){
System.out.println("Operation Not Supported");
return null;
}
}

Beachten Sie, dass dies nicht die einzige Methode ist, sondern eine der vielen möglichen Methoden

0
Jagreet