how to get keys in Map with same sequence as they were inserted
我正在尝试在Map中放入一些键值,并尝试以与插入时相同的顺序检索它们。 例如下面是我的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import java.util.*;
import java.util.Map.Entry;
public class HashMaptoArrayExample {
public static void main (String args [])
{
Map <String,Integer > map = new HashMap <String,Integer >();
// put some values into map
map. put("first", 1);
map. put("second", 2);
map. put("third", 3);
map. put("fourth", 4);
map. put("fifth", 5);
map. put("sixth", 6);
map. put("seventh", 7);
map. put("eighth", 8);
map. put("ninth", 9);
Iterator iterator = map. entrySet(). iterator();
while(iterator. hasNext())
{
Entry entry =(Entry )iterator. next();
System. out. println(" entries="+entry. getKey(). toString());
}
}
} |
我想检索如下的密钥
1
| first second third fourth fifth sixth ..... |
但它在我的输出中以一些随机顺序显示如下
1 2 3
| OUTPUT
ninth eigth fifth first sixth seventh third fourth second |
-
重复?? stackoverflow.com/questions/663374/java-ordered-map
-
java.util.LinkedHashMap并且永远/永远不会使用java.util.HashMap,除非你有非常强大的理由(即减少内存占用和缺少迭代)。 imo,HashMap是java.util中最糟糕的数据结构(也许只能被java.util.Stack打败)
-
@msalvadores不完全是。那个是关于条目被排序的(例如,按字母顺序排列),这个是关于它们按照它们被添加到地图的相同顺序返回的。
-
@bestsss:我采取相反的方法:使用最符合您要求的类型。除非您需要维护插入顺序,否则为什么要使用更复杂(且成本更高)的类型?绝大多数时候,HashMap对我很好。它完全按照它在锡上所说的那样,而且不再 - 你为什么这么喜欢它?
-
@Jon Skeet嗯,简而言之,这就是他所说的。永远不要使用HashMap,除非它是合适的。 :)
-
@Jon Skeet:每个键/值需要2个额外的引用(即x64上的16个字节仍远小于存储桶本身),但它具有可预测且更快的迭代。由于可预测的迭代,如果需要,它允许排队处理。这是绝对罕见的,你只需要获取/放置和没有同步 - 主要是配置,他们最好有适当的迭代。最重要的是:java中的HashMap设计有点缺乏,因为树类相似(带有桶的链表)会对碰撞和桶访问造成整体缓存缺失。
-
@bestsss:相反,我相对很少迭代地图 - 我更可能只是用它来获取/放置。更重要的是,当我使用HashMap而不是LinkedHashMap时,我有效地表达了我不关心排序的事实。
-
@Jon Skeet:..续:另一部分正是树一样的结构。 Java集合框架设计者选择了w / 2 ^ n bucket []大小而不是第一号。 2 ^ n不需要'mod(%)'但是'和(&amp;)'['mod'就像30cpu时钟,'和'就像1]所以当没有发生碰撞时它很好。 LinkedLists可能是迭代最慢的数据类型,因为它非常容易出现缓存错误。因此,当存在冲突时,HashMap会严重降低性能。 IdentityHashMap具有线性探针设计,整体速度更快,并且在put上没有分配。
-
@bestsss:是的,但是然后IdentityHashMap通常不是你想要的行为;)就个人而言,我对Java中的地图类的主要认识是,没有相当于.NET的IEqualityComparer可以让你概括平等关系。
-
@Jon Skeet:至于迭代,它不是地图的主要职责,但它往往发生,我喜欢确保订单被保留并强加队列相似的优先级。作为一个小的优点,它也使调试更容易(因为你可以监视下单)
-
@bestsss:也许我们编写非常不同的应用程序:)我喜欢使用最合适的类型来满足我的实际需求。使用功能更全面的类型表明我可能需要这些额外的功能......当我的需求稍后扩展时,这会使得更难找到不同的类型。
-
@Jon Skeet:对于IdentityHashMap,我只讨论散列+贴图的内部设计(例如基于树的vs线性探针,需要查找Knut的章节)。有时候我也会想念Hashprovider + EqualityComparer,但是他们需要真正的herioc inlining来形成VM以避免虚拟调用(这会使性能下降4-5次)
您不能使用HashMap执行此操作,HashMap不会在其数据中的任何位置维护插入顺序。 看看LinkedHashMap,它是为了维持这个顺序而精心设计的。
-
非常感谢。 它运作得很好。 最后一个问题。 而不是使用iterator.hasNext()我可以使用高级for循环
-
@Sukumar:绝对:for (Map.Entry<..,..> entry : map.entrySet()) { ... }。
-
确定你可以(对于x:y)有效地编译为迭代器; hasNext(),next()
-
非常感谢你们。 它真的帮助了我。
-
LinkedHashMap没有获取特定索引的方法。 在我的情况下,我想要插入最后一个数字。 任何现有的DataStructures都可以这样做吗?
-
@Imray:不确定,说实话......
-
谢谢你!保存我的一天
HashMap是哈希表。 这意味着插入密钥的顺序无关紧要,因为它们不按此顺序存储。 插入另一个密钥的那一刻,忘记了最后一个密钥的信息。
如果要记住插入顺序,则需要使用不同的数据结构。
-
.....哪一个?
-
@Imray看看Jon的回答。