So ersetzen Sie HashMap-Werte, während Sie sie in Java durchlaufen

Lesezeit: 3 Minuten

Ich verwende ein Runnable, um jede Sekunde automatisch 20 von der Abklingzeit eines Spielers abzuziehen, aber ich habe keine Ahnung, wie ich den Wert eines Werts ersetzen soll, während ich ihn durchlaufe. Wie kann ich den Wert jedes Schlüssels aktualisieren lassen?

public class CoolDownTimer implements Runnable {
    @Override
    public void run() {
        for (Long l : playerCooldowns.values()) {
            l = l - 20;
            playerCooldowns.put(Key???, l);
        }
    }

}

Benutzer-Avatar
aiobe

Verwendung von Java 8:

map.replaceAll((k, v) -> v - 20);

Mit Java 7 oder älter:

Sie können die Einträge durchlaufen und die Werte wie folgt aktualisieren:

for (Map.Entry<Key, Long> entry : playerCooldowns.entrySet()) {
    entry.setValue(entry.getValue() - 20);
}

  • Ich kann nicht glauben, dass ich nicht daran gedacht habe. Vielen Dank.

    – Zach Sugano

    12. Juni 2012 um 9:04 Uhr

  • Tatsächlich gibt es für dieses Muster eine FindBugs-Warnung: Ineffiziente Verwendung des keySet-Iterators anstelle des entrySet-Iterators Und selbst wenn es in den meisten Fällen leistungsmäßig keine Rolle spielt, kann es in einigen Fällen einen großen Unterschied machen. Außerdem denke ich sogar, dass der Code in beiden Fällen klar und lesbar ist. Warum ein Muster verwenden und posten, das eindeutig einige Nachteile und keinerlei Vorteile hat? (Auch wenn die Nachteile wohl gering sind)

    – Tim Büthe

    2. Oktober 2015 um 9:58 Uhr


  • @aioobe: Ich kann mir sicher vorstellen, dass dies unterschiedliche Auswirkungen auf verschiedene Kartenimplementierungen hat, aber gibt es eine, bei der die erstere Form der Iteration effizienter ist als die letztere? Und deshalb wäre die FindBugs-Warnung ein Fehlalarm? Aber du hast recht, darüber müssen wir hier nicht diskutieren. Ihre Antwort ist immer noch in Ordnung, denke ich.

    – Tim Büthe

    2. Oktober 2015 um 11:19 Uhr


  • Können Sie erklären, warum das funktioniert? Soweit ich mich erinnere, dürfen Sie Elemente einer Sammlung nicht ändern, während Sie sie mit einer for each-Schleife durchlaufen.

    – Alex Li

    12. April 2018 um 18:42 Uhr

  • Du darfst das nicht strukturell Änderungen wie das Hinzufügen oder Entfernen von Elementen.

    – aiobe

    12. April 2018 um 19:19 Uhr

Benutzer-Avatar
Jon

Nun, Sie können dies nicht tun, indem Sie über den Satz von Werten in iterieren Map (wie Sie es jetzt tun), denn wenn Sie das tun, haben Sie keinen Bezug zu den Schlüsseln, und wenn Sie keinen Bezug zu den Schlüsseln haben, können Sie die Einträge in der Karte nicht aktualisieren, da Sie keine Möglichkeit dazu haben herauszufinden, welcher Schlüssel mit dem gerade aktualisierten Wert verknüpft war.

Wenn Sie mit Maps arbeiten, haben Sie zwei Optionen für solche Updates, die Sie jeweils durchlaufen Map.Entry<K,V> in dem Mapoder Sie können den Schlüssel durchlaufen Set. Es gibt Methoden auf Map diese beiden Dinge zu tun. Persönlich würde ich jeden durchlaufen Map.Entry<K,V>.

for (Map.Entry<String, Long> entry : playerCooldowns.entrySet()) {
    entry.setValue(entry.getValue() - 20);
}

Warum nicht über die iterieren Karte.Eintrag Objekte? Jeder Entry gibt Ihnen den Schlüssel und Wert und Sie müssen nichts weiter tun get() auf der Map einen Wert zu bekommen.

1186900cookie-checkSo ersetzen Sie HashMap-Werte, während Sie sie in Java durchlaufen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy