维护HashMap中的顺序
我有一个列表,我转换为地图做一些工作。 之后,我将地图再次转换回列表,但这次订单是随机的。 我需要在第二个列表中保留相同的初始订单。
显而易见的原因是HashMap没有维护顺序。 但我需要做一些事情才能做到。 我不能改变Map的实现。我怎么能这样做?
考虑给定的代码:
import java.util.*; public class Dummy { public static void main(String[] args) { System.out.println("Hello world !"); List list = new ArrayList(); list.add("A");list.add("B");list.add("C"); list.add("D");list.add("E");list.add("F"); Map map = new HashMap(); for(int i=0;i<list.size();i=i+2) map.put(list.get(i),list.get(i+1)); // Use map here to do some work List l= new ArrayList(); for (Map.Entry e : map.entrySet()) { l.add((String) e.getKey()); l.add((String) e.getValue()); } } }
对于ex – 最初,当我打印列表元素时,它打印出来
ABCDEF
现在,当我打印List l
的元素时,它打印出来
EFABCD
HashMap
本身不维护插入顺序 – 但是LinkedHashMap
,所以请改用它。
记录在案…… HashMap
:
这个类不保证地图的顺序; 特别是,它不保证订单会随着时间的推移保持不变。
和LinkedHashMap
:
Map接口的哈希表和链表实现,具有可预测的迭代顺序。 此实现与HashMap的不同之处在于它维护了一个贯穿其所有条目的双向链表。 此链接列表定义迭代排序,通常是键插入映射的顺序(插入顺序)。
使用LinkedHashMap而不是HashMap来维护顺序。
Map map = new LinkedHashMap();
为什么不能更改Map
实现(例如LinkedHashMap
)?
如果存在逻辑排序,则可以使用自定义Comparator
对List进行排序。
HashMap
不保留插入顺序
基于哈希表的Map接口实现。 此实现提供所有可选的映射操作,并允许空值和空键。 (HashMap类大致相当于Hashtable,除了它是不同步的并且允许空值。)这个类不保证地图的顺序; 特别是,它不保证订单会随着时间的推移保持不变。
如果要保留键的顺序,请使用LinkedHashMap
考虑使您的项目可排序。 在字符串的情况下,已经有了自然的顺序; 按字母顺序排列。 您可以创建使用可排序类的对象,因此您可以使用排序算法将这些对象放在一个很好的顺序中,无论您从哈希中获取它们的顺序如何!
现在是LinkedHashMap
的时候了,它正是为了保留插入顺序。
请注意,即使存在TreeMap
,也可以使用Comparable接口保持所需的顺序。 它不再是哈希映射,而是一棵树。
如果您真的无法切换到另一个Map
实现(LinkedHashMap
正是您想要的),那么唯一的另一种可能性是保留原始List,
并使用它从Map.
创建新List
Map.
public List listFromMapInOrder(final Map map, final List order) { List result = new ArrayList (); for (T key : order) { if (map.containsKey(key)) { result.add(key); result.add(map.get(key)); } } return result; }
但我会重构代码,直到可以切换到LinkedHashMap.