1

为什么 hash table( java.util.HashMap) 按longintbyteshort排序?

见下面的代码:

public class Main {

    private static final int INITIAL_CAPACITY = 10;

    public static void main(String[] args) {

        final Map<Long, Long> longMap = new HashMap<>(INITIAL_CAPACITY);
        final Map<Integer, Integer> integerMap = new HashMap<>(INITIAL_CAPACITY);
        final Map<Byte, Byte> byteMap = new HashMap<>(INITIAL_CAPACITY);
        final Map<Short, Short> shortMap = new HashMap<>(INITIAL_CAPACITY);

        final Map<Double, Double> doubleMap = new HashMap<>(INITIAL_CAPACITY);
        final Map<Float, Float> floatMap = new HashMap<>(INITIAL_CAPACITY);
        final Map<BigDecimal, BigDecimal> bigDecimalMap = new HashMap<>(INITIAL_CAPACITY);
        final Map<String, String> stringMap = new HashMap<>(INITIAL_CAPACITY);

        final Random random = new Random();

        for(int i=0; i < 100; i++){

            int value = random.nextInt(10);
            longMap.put(Long.valueOf(value), Long.valueOf(value));
            integerMap.put(Integer.valueOf(value), Integer.valueOf(value));
            byteMap.put(Byte.valueOf((byte)value), Byte.valueOf((byte)value));
            shortMap.put(Short.valueOf((short)value), Short.valueOf((short)value));

            doubleMap.put(Double.valueOf(value), Double.valueOf(value));
            floatMap.put(Float.valueOf(value), Float.valueOf(value));
            bigDecimalMap.put(BigDecimal.valueOf(value), BigDecimal.valueOf(value));
            stringMap.put(String.valueOf(value), String.valueOf(value));
        }

        System.out.println("\n========== SORTED ==========\n");
        System.out.println("Map<Long, Long>:             " + longMap);
        System.out.println("Map<Integer, Integer>:       " + integerMap);
        System.out.println("Map<Byte, Byte>:             " + byteMap);
        System.out.println("Map<Short, Short>:           " + shortMap);
        System.out.println("\n======== NOT SORTED ========\n");
        System.out.println("Map<Double, Double>:         " + doubleMap);
        System.out.println("Map<Float, Float>:           " + floatMap);
        System.out.println("Map<BigDecimal, BigDecimal>: " + bigDecimalMap);
        System.out.println("Map<String, String>: " + stringMap);
    }

}

输出这个程序:

========== SORTED ==========

Map<Long, Long>             : {0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}
Map<Integer, Integer>       : {0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}
Map<Byte, Byte>             : {0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}
Map<Short, Short>           : {0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}

======== NOT SORTED ========

Map<Double, Double>         : {0.0=0.0, 3.0=3.0, 6.0=6.0, 7.0=7.0, 2.0=2.0, 1.0=1.0, 4.0=4.0, 9.0=9.0, 8.0=8.0, 5.0=5.0}
Map<Float, Float>           : {1.0=1.0, 0.0=0.0, 4.0=4.0, 3.0=3.0, 5.0=5.0, 2.0=2.0, 8.0=8.0, 9.0=9.0, 7.0=7.0, 6.0=6.0}
Map<BigDecimal, BigDecimal> : {6=6, 0=0, 5=5, 9=9, 7=7, 8=8, 3=3, 4=4, 2=2, 1=1}
Map<String, String>         : {3=3, 2=2, 1=1, 0=0, 7=7, 6=6, 5=5, 4=4, 9=9, 8=8}
4

2 回答 2

5

因为 for Long, Integer,ByteShort被覆盖的int hashCode()方法是微不足道的并且返回数值本身。由于哈希码用于索引元素放置在哈希图中的特定存储桶,因此较低的哈希会导致较低的索引。请注意,保留的顺序很明显:通过将其他元素添加到哈希映射中,很可能会在同一个存储桶中放置更多元素,因此无法保证您看到的内容,这只是可能出现的副作用。HashMap不是一个排序的集合,你不应该这样使用它TreeMap当您需要排序对时,这是要走的路。

对于Double, Float,BigIntegerString哈希码函数不那么简单,因此不保留顺序。

于 2013-11-08T06:55:10.083 回答
2

HashMap 没有排序,你的结果只是偶然的。尝试这个

    Map<Long, Long> m = new HashMap<>();
    m.put(1001L, 1001L);
    m.put(1000L, 1000L);
    m.put(1002L, 1002L);
    System.out.println(m);

输出

{1001=1001, 1000=1000, 1002=1002}

-- 不排序

于 2013-11-08T07:07:47.273 回答