如何保持哈希表中元素的顺序?

26

我有一个哈希表。values()方法返回的值的顺序与我插入的顺序不同。如何以插入顺序获取这些值?使用LinkedHashmap是一种替代方案,但它不是同步的。


你使用的是哪种编程语言? - Van Gale
LinkedHashMap 是 Java 的一部分。 - jimyi
5个回答

37

使用LinkedHashMap

Map接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与HashMap不同之处在于,它维护通过所有条目的双向链接列表。此链接列表定义了迭代顺序,通常是将键插入到映射中的顺序(即“插入顺序”)。请注意,如果将键重新插入到映射中,则不会影响插入顺序。(如果在调用m.put(k, v)之前立即调用m.containsKey(k)将返回true,则称键k被重新插入到映射m中。)

结合Collections.synchronizedMap()使用。

例如:

Map<String, String> map = Collections.synchronizedMap(
  new LinkedHashMap<String, String>());

澄清一下:如果我不考虑同时让多个线程访问这个LinkedHashMap,那么是否仍建议对其进行同步?还是说LinkedHashMap本身就足够了? - blo0p3r
1
@blo0p3r LinedHashMap本身应该足够了。 - Priidu Neemre

4

您可以将LinkedHashMap进行包装并同步,或者使用Collections.synchronizedMap实用程序创建一个同步的LinkedHashMap

Map m = Collections.synchronizedMap(new LinkedHashMap(...));

根据JavaDoc:

如果多个线程同时访问一个链接哈希映射,并且其中至少一个线程在结构上修改了该映射,则必须在外部进行同步。通常通过在自然地封装映射的某个对象上同步来实现这一点。如果不存在这样的对象,则应使用Collections.synchronizedMap方法“包装”映射。最好在创建时完成此操作,以防止意外的非同步访问映射。


性能开销将是可以忽略不计的(字面上是纳秒级别的)。 - Adamski

3

我相信哈希表不排序的原因是为了提高存储和检索速度。因此,我建议使用外部结构来维护顺序,只使用哈希表来存储值(以实现快速查找)。


2

哈希表本质上是无序的,所以您使用了错误的数据结构。由于您没有指定使用的语言,我无法建议替代方案,但您需要一些类型的有序键/值集合。


1
如果你使用的是jdk1.6,那么你只有两种有序映射类型:EnumMap和LinkedHashMap。它们都不是同步的。如果你只需要记住顺序,那就使用LinkedHashMap。
Map m = Collections.synchronizedMap(new LinkedHashMap(...));

如果你想要排序,那么使用ConcurrentSkipListMap。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接