Java ConcurrenLinkedHashMap迭代器提供的元素顺序取决于键大小?

Java ConcurrenLinkedHashMap迭代器提供的元素顺序取决于键大小?,java,guava,Java,Guava,我发现(迭代器?)ConcurrentLinkedHashMap的奇怪行为。 如果键长,则通过迭代entrySet/keySet获得的元素的顺序是奇怪的/意外的。如果钥匙短,一切都好 以下代码: public static void main(String[] args) { ConcurrentLinkedHashMap<String, String> map = new ConcurrentLinkedHashMap.Builder<

我发现(迭代器?)ConcurrentLinkedHashMap的奇怪行为。 如果键长,则通过迭代entrySet/keySet获得的元素的顺序是奇怪的/意外的。如果钥匙短,一切都好

以下代码:

    public static void main(String[] args) {
    ConcurrentLinkedHashMap<String, String> map =
            new ConcurrentLinkedHashMap.Builder<String, String>().maximumWeightedCapacity(1000).build();
    for (int i = 0; i < 5; i++) {
        map.put(i + "", i + "");
    }
    print(map);
    map.clear(); 
    // NOW AGAIN THE SAME, BUT WITH LONG KEY
    for (int i = 0; i < 5; i++) {
        map.put(i + "aaaaaaaaaaaaaaaaaaaaaaaaaa" +
                "aaaaaaaaaaaaaaaaaaaaaaaaaa" +
                "aaaaaaaaaaaaaaaaaaaaaaaaaa", i + "");
    }
    print(map);
}

private static void print(ConcurrentLinkedHashMap<String, String> a) {
    Iterator iterator = a.entrySet().iterator();
    while (iterator.hasNext()) {
        System.out.println(" = " + iterator.next());
    }
}
这很奇怪。 如果我使键变长,结果就不同了

是虫子吗?我怎样才能得到正确的结果? (第二个“打印”结果的顺序应与第一个相同)

java.util.LinkedHashMap
不同,此类不提供可预测的迭代顺序。 ()

文档对此相当清楚-因此没有bug

关于迭代项的顺序,
ConcurrentLinkedHashMap
提供了键的保留顺序。这可能并不总是您的目标,但至少对于给定的测试场景,在给定以下代码的情况下,返回一个有序的输出:

private static void print(ConcurrentLinkedHashMap<String, String> a)
{
    Iterator iterator = a.entrySet().iterator();
    while (iterator.hasNext())
    {
        System.out.println(" = " + iterator.next());
    }
    Iterator<String> iter = a.ascendingKeySet().iterator();
    while (iter.hasNext()) 
    {
        String key = iter.next();
        System.out.println(key + " -> " + a.get(key));
    }
}

你用的是什么版本的番石榴?@assylias根据git的说法,它从来都不是番石榴的一部分,它只是为
MapMaker
CacheBuilder
设计的。好吧,是的,谢谢。Strage为什么它被称为Linked*。@user\x更新了我的帖子,加入了一些关于
ascendingKeySet
@user\x的信息。该类提供了LinkedHashMap的
access order=true
功能,这在多线程中更为常见,并且难以扩展。相比之下,插入顺序并发映射相对来说微不足道。
private static void print(ConcurrentLinkedHashMap<String, String> a)
{
    Iterator iterator = a.entrySet().iterator();
    while (iterator.hasNext())
    {
        System.out.println(" = " + iterator.next());
    }
    Iterator<String> iter = a.ascendingKeySet().iterator();
    while (iter.hasNext()) 
    {
        String key = iter.next();
        System.out.println(key + " -> " + a.get(key));
    }
}
 = 0=0
 = 1=1
 = 2=2
 = 3=3
 = 4=4
0 -> 0
1 -> 1
2 -> 2
3 -> 3
4 -> 4
 = 1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1
 = 4aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=4
 = 2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=2
 = 3aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=3
 = 0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=0
0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> 0
1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> 1
2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> 2
3aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> 3
4aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> 4