Wie füge ich ein Element an einem bestimmten Index / einer bestimmten Position in LinkedHashMap hinzu?

Lesezeit: 8 Minuten

Benutzer-Avatar
Supernova

Ich habe eine bestellte LinkedHashMap und möchte ein Element an einem bestimmten Index hinzufügen, z. B. an erster oder letzter Stelle in der Karte. Wie kann ich ein Element in LinkedHashMap an einer bestimmten Position hinzufügen?

Selbst wenn ich ein Element zur ERSTEN oder LETZTEN Position in LinkedHashMap hinzufügen könnte, würde das helfen!

  • Aus den Dokumenten: „Beachten Sie, dass die Einfügungsreihenfolge nicht beeinflusst wird, wenn ein Schlüssel erneut in die Karte eingefügt wird. (Ein Schlüssel k wird erneut in eine Karte m eingefügt, wenn m.put(k, v) aufgerufen wird, wenn m.containsKey(k ) würde unmittelbar vor dem Aufruf true zurückgeben.)”

    – Andreas

    10. Dezember 2018 um 18:38 Uhr

Benutzer-Avatar
Gyurix

Sie könnten dieses Element zur 1. oder letzten Stelle hinzufügen:

Hinzufügen zum letzten Platz ► Sie müssen nur den vorherigen Eintrag wie folgt aus der Karte entfernen:

map.remove(key);
map.put(key,value);

Hinzufügen zum ersten Platz ► Es ist etwas komplizierter, Sie müssen die Karte klonen, löschen, den 1. Wert hinzufügen und die neue Karte hinzufügen, wie folgt:

Ich verwende Karten mit String-Schlüsseln und Gruppenwerten (meine benutzerdefinierte Klasse):

LinkedHashMap<String, Group> newMap=(LinkedHashMap<String, Group>) map.clone();
map.clear();
map.put(key, value);
map.putAll(newMap);

Wie Sie sehen, können Sie mit diesen Methoden unbegrenzt viele Dinge am Anfang und am Ende der Karte hinzufügen.

  • Beachten Sie, dass mit dieser Methode eine Kopie der Objekte in der Karte erstellt wird. Etwas könnte kaputt gehen, wenn Sie diese Objekte anderweitig verwenden.

    – Omaraf

    3. August 2017 um 7:12 Uhr

  • Beachten Sie den dadurch entstehenden Speicher-Overhead. Vermeiden Sie es am besten, dies zu verwenden.

    – Simon Baar

    6. Oktober 2017 um 10:38 Uhr

  • @Omaraf erstellt eine flache Kopie der Karte. Am Ende ist “map” das gleiche Objekt und Schlüssel und Werte sind auch die gleichen Objekte. Wenn die Karte nicht viele Schlüssel hat, wird der Speicheraufwand nicht riesig sein. Aber natürlich – wenn Sie können – verwenden Sie dafür eine andere Datenstruktur 🙂

    – Fehler_

    26. Juli 2021 um 9:24 Uhr


Benutzer-Avatar
Tobias

Sie können die Reihenfolge nicht ändern. es ist insert-order (standardmäßig) oder access-order mit diesem Konstruktor:

public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)

  • Erstellt eine leere LinkedHashMap-Instanz mit der angegebenen Anfangskapazität, dem Lastfaktor und dem Sortiermodus.

  • Parameter: initialCapacity – die Anfangskapazität loadFactor – der Lastfaktor accessOrder – der Sortiermodus – true für die Zugriffsreihenfolge, false für die Einfügungsreihenfolge

  • Löst aus: IllegalArgumentException – wenn die anfängliche Kapazität negativ oder der Lastfaktor nicht positiv ist

Sehen: LinkedHashMap

  • Tks. Es bedeutet, dass NUR die Bestellung, zu der ich ein Element hinzufügen kann, LETZTER Platz ist. Wie Sie bereits erwähnt haben, behält es die Reihenfolge bei, also bin ich davon ausgegangen, dass es am letzten Index jedes neue Element hinzufügen wird! Eigentlich musste ich nur Elemente an der ERSTEN oder LETZTEN Stelle hinzufügen. Letzter Ort, den ich bekommen kann, denn um an erster Stelle hinzuzufügen, kann ich das am Ende zu einer anderen Karte hinzufügen?

    – Supernova

    6. Oktober 2011 um 20:17 Uhr

  • Sie könnten eine neue Liste mit dem neuen Element erstellen und die komplette andere Liste danach mit addAll(); aber das ist Speicherverschwendung und die Karte ist nicht für diesen Zweck erstellt.

    – Tobias

    6. Oktober 2011 um 20:20 Uhr

  • Tks.That sieht aus wie die einzige Lösung mit LinkedHashMap.

    – Supernova

    6. Oktober 2011 um 20:27 Uhr

  • @supernova Sie können jederzeit Ihre eigenen erstellen, dies ist keine Einschränkung einer LinkedHashMap, sondern eine Einschränkung der LinkedHashMap-Implementierung von Java

    – Schrittmacher

    24. April 2012 um 22:26 Uhr


Apache Commons-Lösung: ListOrderedMap

Da die JDK’s LinkedHashMap stellt nur das Abrufen der Insertionsreihenfolge sicher, falls Sie in einen Index einfügen möchten, können wir alternativ Apache Commons verwenden. ListOrderedMap. Es macht es so, wie es sich anhört – indem es eine Liste hat, um die Reihenfolge des Einfügens mit dem entsprechenden Index und einer normalen Karte zum Einfügen beizubehalten, wie wir es normalerweise tun. Hier ist, was die Dokumente sagen:

public class ListOrderedMap<K,V>
extends AbstractMapDecorator<K,V>
implements OrderedMap<K,V>, Serializable

Schmückt ein Map um sicherzustellen, dass die Reihenfolge des Hinzufügens beibehalten wird, indem eine Liste verwendet wird, um die Reihenfolge aufrechtzuerhalten.

Die Reihenfolge wird über die Iteratoren und verwendet toArray Methoden auf die Ansichten. Die Bestellung wird auch von der zurückgegeben MapIterator. Das
orderedMapIterator() -Methode greift auf einen Iterator zu, der sowohl vorwärts als auch rückwärts durch die Karte iterieren kann. Zusätzlich werden schnittstellenfreie Verfahren bereitgestellt, um auf die Karte nach Index zuzugreifen.

Wenn ein Objekt ein zweites Mal zur Karte hinzugefügt wird, bleibt es in der Iteration an der ursprünglichen Position.

Beachten Sie, dass ListOrderedMap wird nicht synchronisiert und ist nicht Thread-sicher. Wenn Sie diese Zuordnung von mehreren Threads gleichzeitig verwenden möchten, müssen Sie eine entsprechende Synchronisierung verwenden. Der einfachste Ansatz besteht darin, diese Karte mit einzuwickeln Collections.synchronizedMap(Map). Diese Klasse kann Ausnahmen auslösen, wenn sie von gleichzeitigen Threads ohne Synchronisierung aufgerufen wird.

Beachten Sie, dass ListOrderedMap funktioniert nicht mit IdentityHashMap,
CaseInsensitiveMapoder ähnliche Karten, die gegen den allgemeinen Vertrag verstoßen Map. Das ListOrderedMap (genauer gesagt der Basiswert List) stützt sich auf equals(). Das ist in Ordnung, solange das dekoriert ist Map basiert auch auf equals()und hashCode()die IdentityHashMapund CaseInsensitiveMap don’t: Erstere verwendet ==und letztere verwendet equals() auf einer Kleinbuchstabentaste.

Hier ist die Implementierung zum Hinzufügen zu einer Position:

        /**
428     * Puts a key-value mapping into the map at the specified index.
429     * <p>
430     * If the map already contains the key, then the original mapping
431     * is removed and the new mapping added at the specified index.
432     * The remove may change the effect of the index. The index is
433     * always calculated relative to the original state of the map.
434     * <p>
435     * Thus the steps are: (1) remove the existing key-value mapping,
436     * then (2) insert the new key-value mapping at the position it
437     * would have been inserted had the remove not occurred.
438     *
439     * @param index  the index at which the mapping should be inserted
440     * @param key  the key
441     * @param value  the value
442     * @return the value previously mapped to the key
443     * @throws IndexOutOfBoundsException if the index is out of range [0, size]
444     * @since 3.2
445     */
446    public V put(int index, final K key, final V value) {
447        if (index < 0 || index > insertOrder.size()) {
448            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + insertOrder.size());
449        }
450
451        final Map<K, V> m = decorated();
452        if (m.containsKey(key)) {
453            final V result = m.remove(key);
454            final int pos = insertOrder.indexOf(key);
455            insertOrder.remove(pos);
456            if (pos < index) {
457                index--;
458            }
459            insertOrder.add(index, key);
460            m.put(key, value);
461            return result;
462        }
463        insertOrder.add(index, key);
464        m.put(key, value);
465        return null;
466    }

Benutzer-Avatar
Tamalet

public static <K, V> void add(LinkedHashMap<K, V> map, int index, K key, V value) {
  assert (map != null);
  assert !map.containsKey(key);
  assert (index >= 0) && (index < map.size());

  int i = 0;
  List<Entry<K, V>> rest = new ArrayList<Entry<K, V>>();
  for (Entry<K, V> entry : map.entrySet()) {
    if (i++ >= index) {
      rest.add(entry);
    }
  }
  map.put(key, value);
  for (int j = 0; j < rest.size(); j++) {
    Entry<K, V> entry = rest.get(j);
    map.remove(entry.getKey());
    map.put(entry.getKey(), entry.getValue());
  }
}

Teile dich einfach LinkedHashMap auf 2 Reihen. Erstellen Sie das erste Array mit der Größe index - 1 und am Ende neu setzen Entry. Füllen Sie dann das erste Array mit Einträgen aus dem zweiten

Es ist ein Map, es hat keine Indizes. Es hat Eimer. Die Art und Weise, wie es funktioniert, ist, wenn Sie a tun

put(key, val)

Es hasht den Schlüssel, um herauszufinden, in welchen Bucket das Val gesteckt werden soll.

Das LinkedHashMap verwaltet eine doppelt verknüpfte Liste, damit sie die Reihenfolge aufzeichnen kann, in der Einträge eingefügt werden (oder auf die zugegriffen wird, je nachdem, wie Sie die Karte instanziieren). Es gibt keine Methode in der API auf der Karte, um ein Schlüssel-Wert-Paar an einem bestimmten Index der verknüpften Liste einzufügen, da dies nicht der Zweck ist, den es erfüllt.

Benutzer-Avatar
Nauman Aejaz

...

LinkedHashMap<String, StringExtension> map = new LinkedHashMap<>();

map.put("4", new StringExtension("4", "a"));
map.put("1", new StringExtension("1", "b"));
map.put("3", new StringExtension("3", "c"));
map.put("2", new StringExtension("2", "d"));

for (Map.Entry<String, StringExtension> entry : map.entrySet()) {
    Log.e("Test", "" + entry.getKey() + " - "+ entry.getValue().value);
}


Collection<StringExtension> temp = new ArrayList<>(map.values());
StringExtension value = map.remove("3");
map.clear();
map.put(value.key, value);

for (StringExtension val : temp) {
    map.put(val.key, val);
}

Log.e("Test", "---");

for (Map.Entry<String, StringExtension> entry : map.entrySet()) {
    Log.e("Test", "" + entry.getKey() + " - "+ entry.getValue().value);
}

...

private class StringExtension
{
    String key;
    String value;

    public StringExtension(String key, String value) {
        this.key = key;
        this.value = value;
    }
}

  • Das ist ein bisschen lang für eine so einfache Frage.

    – Alexander

    1. Mai 2018 um 21:32 Uhr

  • Einverstanden. Ich hatte das gleiche Problem und habe keinen besseren Weg gefunden.

    – Nauman Aejaz

    3. Mai 2018 um 4:23 Uhr

1062430cookie-checkWie füge ich ein Element an einem bestimmten Index / einer bestimmten Position in LinkedHashMap hinzu?

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

Privacy policy