Comment ajouter un élément à index/position spécifique dans LinkedHashMap?
J'ai un LinkedHashMap ordonné et je veux ajouter l'élément à l'index spécifique , disons à la première ou à la dernière place dans 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 première ou dernière position dans LinkedHashMap serait utile!
7 réponses
Vous ne pouvez pas modifier l'ordre. C'est insert-order
(par défaut) ou access-order
avec ce constructeur:
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
construit une instance LinkedHashMap vide avec la capacité initiale spécifiée, le facteur de charge et le mode d'ordre.
Paramètres: initialCapacity - la capacité initiale facteur de charge-le facteur de charge accessOrder-le mode de commande-true pour access-order, false pour insertion d'ordre
lancers: IllegalArgumentException-si la capacité initiale est négative ou si le facteur de charge n'est pas positif
Voir: LinkedHashMap
vous pouvez ajouter cet élément à 1. ou à la dernière place:
ajouter à la dernière place► Vous avez juste besoin 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, effacer, mettre le 1. de valeur, et de mettre la nouvelle carte, comme ceci:
j'utilise des cartes avec des clés String et des valeurs de groupe (ma classe personnalisée):
LinkedHashMap<String, Group> newmap=(LinkedHashMap<String, Group>) map.clone();
map.clear();
map.put(key, value);
map.putAll(newm);
Comme vous voyez, avec ces méthodes, vous pouvez ajouter un nombre illimité de choses au début et à la fin de la carte.
il suffit de vous diviser!--0--> sur les 2 tableaux. Faire le premier tableau avec la taille index - 1
et à la fin de la nouvelle Entry
. Ensuite, remplissez le premier tableau avec les entrées de la deuxième
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());
}
}
Apache Commons solution:ListOrderedMap
Depuis le JDK LinkedHashMap
assure seulement la récupération de l'ordre d'insertion, dans le cas où vous voulez insérer à un index, Nous pouvons utiliser alternativement Apache Commons'ListOrderedMap
. Il le fait qu'il y paraît, en ayant une liste de maintenir l'ordre d'insertion avec l'index correspondant et une normal map pour insérer comme nous le faisons généralement. Voici ce que l' docs dis:
public class ListOrderedMap<K,V> extends AbstractMapDecorator<K,V> implements OrderedMap<K,V>, Serializable
Orne
Map
pour vous assurer la position initiale 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 devez utiliser la synchronisation appropriée. L'approche la plus simple est d'envelopper cette carte à l'aide deCollections.synchronizedMap(Map)
. Cette classe peut lancer des exceptions lorsqu'il est accédé par des threads concurrents sans synchronisation.Notez que
ListOrderedMap
ne fonctionne pas avecIdentityHashMap
,CaseInsensitiveMap
, ou des cartes similaires qui violer le général contrat deMap
.ListOrderedMap
(ou, plus précisément, l' sous-jacentList
) s'appuie surequals()
. Ce qui est bien, aussi longtemps que la décoréesMap
est aussi basé surequals()
ethashCode()
,IdentityHashMap
etCaseInsensitiveMap
ne pas faire: le premier utilise==
, et ce dernier utiliseequals()
sur une touche plus basse.
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 }
C'est un Map
, il n'a pas d'index. Il a des seaux. La façon dont il fonctionne, c'est quand tu fais un
put(key, val)
il hache la clé pour trouver dans quel seau mettre le val.
LinkedHashMap
maintient une liste doublement liée de sorte qu'il peut enregistrer l'ordre dans lequel les entrées sont insérées (ou accessibles, selon la façon dont vous instanciez la carte). Il n'y a pas de méthode sur L'API sur la carte pour insérer une clé,val paire à un certain index de la liste liée, parce que ce n'est pas le but qu'il sert.
...
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;
}
}