J'ai commandé un LinkedHashMap et je veux ajouter un élément à un index spécifique, par exemple au premier ou dernier endroit de la carte ..__ Comment puis-je ajouter un élément dans LinkedHashMap à une position spécifique?
Même si je pouvais ajouter un élément à la position FIRST ou LAST dans LinkedHashMap, cela aiderait!
Vous pouvez faire cet élément en ajoutant à 1. ou à la dernière place:
Ajout au dernier lieu ► Il vous suffit de supprimer l'entrée précédente de la carte, comme ceci:
map.remove(key);
map.put(key,value);
Ajouter à la première place ► C'est un peu plus compliqué, vous devez cloner la carte, la supprimer, lui attribuer la valeur 1., puis y placer la nouvelle carte, comme suit:
J'utilise des cartes avec des clés String et des valeurs Group (ma classe personnalisée):
LinkedHashMap<String, Group> newmap=(LinkedHashMap<String, Group>) map.clone();
map.clear();
map.put(key, value);
map.putAll(newm);
Comme vous le voyez, avec ces méthodes, vous pouvez ajouter un nombre illimité d'éléments au début et à la fin de la carte.
ListOrderedMap
Comme la variable LinkedHashMap
du JDK garantit uniquement l'extraction de l'ordre d'insertion, si vous souhaitez insérer un index, vous pouvez également utiliser la variable ListOrderedMap
d'Apache Commons. Il le fait comme il semble - en ayant une liste pour maintenir l'ordre d'insertion avec l'index correspondant et une carte normale à insérer comme nous le faisons généralement. Voici ce que disent les docs :
public class ListOrderedMap<K,V> extends AbstractMapDecorator<K,V> implements OrderedMap<K,V>, Serializable
Décore une
Map
pour s'assurer que l'ordre d'addition est conservé en utilisant une liste pour maintenir l'ordre.La commande sera utilisée via les itérateurs et les méthodes
toArray
sur le fichier vues. La commande est également retournée par leMapIterator
. Le La méthodeorderedMapIterator()
accède à un itérateur qui peut effectuer une itération en avant et en arrière sur la carte. En outre, des méthodes non-interface sont fournies pour accéder à la carte par index.Si un objet est ajouté à la carte pour la deuxième fois, il restera dans la position d'origine dans l'itération.
Notez que
ListOrderedMap
n'est pas synchronisé et n'est pas thread-safe . Si vous souhaitez utiliser cette carte à partir de plusieurs threads simultanément, vous doit utiliser la synchronisation appropriée. L'approche la plus simple consiste à envelopper cette carte en utilisantCollections.synchronizedMap(Map)
. Cette classe peut émet des exceptions en cas d'accès par des threads concurrents sans synchronisation.Notez que
ListOrderedMap
ne fonctionne pas avecIdentityHashMap
,CaseInsensitiveMap
, ou des cartes similaires qui violent le général contrat deMap
. LaListOrderedMap
(ou, plus précisément, le Sous-jacentList
) s'appuie surequals()
. C'est bien, tant que laMap
décorée est également basée surequals()
ethashCode()
, queIdentityHashMap
etCaseInsensitiveMap
ne font pas: L'ancien utilise==
, et ce dernier utiliseequals()
sur une clé minuscule.
Voici son implémentation pour ajouter à une 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 }
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());
}
}
Il suffit de vous diviser LinkedHashMap
sur 2 tableaux. Faire le premier tableau avec la taille index - 1
et mettre à la fin new Entry
Puis remplissez le premier tableau avec les entrées du second
...
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;
}
}