java - 在LinkedHashMap中,如何在特定索引/位置添加元素?

如何在指定位置的LinkedHashMap中添加元素?

即使我可以在LinkedHashMap的第一个或者最后一个位置添加一个元素,也会有帮助!

时间:

你无法改变排序。它是insert-order (默认情况)或带有此构造函数的access-order

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

  • 构造一个具有指定初始容量,加载因子和排序模式的空LinkedHashMap实例。

  • 参数:initialCapacity - 初始容量loadFactor - 加载因子accessOrder - 排序模式 - 访问顺序为true,插入顺序为false,

  • 抛出:如果初始容量为负或者加载因子为正则,则抛出,

请参阅: LinkedHashMap

你可以将此元素添加到1.或最后一个位置:

添加到最后一个位置,你需要像这样从映射中删除先前的条目:

 

map.remove(key);


map.put(key,value);



添加到第一个位置有点复杂,需要克隆map,清除它,将1.值放到其中,如下所示:

我使用带有字符串键和Group(我的自定义类)值的映射:

 

LinkedHashMap<String, Group> newmap=(LinkedHashMap<String, Group>) map.clone();


map.clear();


map.put(key, value);


map.putAll(newm);



如你所见,使用这些方法,你可以在地图的开始和结尾添加无限量的内容。

只需将 LinkedHashMap 除以 2数组,以大小为 index - 1的第一个 array,并放置在新的Entry 上。 然后将第一个array填充到第二个

 

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解决方案:ListOrderedMap

因为JDK的LinkedHashMap只保证了插入顺序的检索,如果你想在索引上插入我们可以选择使用Apache Commons',以下是文档的内容:

 

public class ListOrderedMap<K,V>


extends AbstractMapDecorator<K,V>


implements OrderedMap<K,V>, Serializable



修饰 Map 以确保使用列表保留添加顺序以保持顺序。

命令将通过视图中的迭代器和toArray方法使用,MapIterator还返回了订单,orderedMapIterator()方法访问一个迭代器,迭代器可以通过映射遍历向前和向后,此外,还提供了非接口方法以通过索引访问地图。

如果一个对象被添加到地图的第二次,它将保留在迭代中的原始位置。

注意,ListOrderedMap不是同步的,并且不是线程安全的,如果希望同时使用多个线程中的映射,则必须使用适当的同步,最简单的方法是使用 Collections.synchronizedMap(Map) 包装这个地图,这里类在没有同步的并发线程访问时可能引发异常。

注意ListOrderedMap不能与IdentityHashMapCaseInsensitiveMap或类似映射一起使用,这些映射违反了Map的一般约定,ListOrderedMap (或者更确切地说是底层的List )依赖equals() ,这很好,只要修饰的Map也基于equals(),并且且hashCode(),IdentityHashMap和CaseInsensitiveMap不是: 前者使用==,后者在较低的套接字密钥上使用equals()

以下是添加到一个位置的实现:

 

 /**


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 }



 

...



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;


 }


}



...