2013-11-08 3 views
1

Почему хэш-таблица (java.util.HashMap) сортируются по долго, INT, байт и короткие?Почему хеш-таблица сортируется?

См код ниже:

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} 
+1

Там нет нигде ничего, что определяет любой из них сортируется. Любая сортировка, которую вы видите, случайна и не полагается на нее. – EJP

+1

Сортировка основана на том, что разработчики не ушли оттуда, чтобы усложнить реализацию. Есть простые случаи использования, когда вы получаете прямой результат. Поскольку вы продолжаете добавлять целые ключи, вы увидите, что расположение псевдослучайно. Коэффициент мощности и нагрузки играют определенную роль, и если вы создадите емкость 1 и коэффициент загрузки 100, вы увидите ключи в обратном порядке, которые вы добавили. http://vanillajava.blogspot.co.uk/2011/09/order-of-elements-in-hash-collection.html –

+1

BTW. Действительная емкость HashMap - это мощность 2, по умолчанию 16, поэтому, когда вы устанавливаете емкость в 10, это то же самое, что не устанавливать ее вообще. –

ответ

5

Потому что для Long, Integer, Byte и Short переопределенном int hashCode() метод тривиален и возвращает сам числовое значение. Поскольку хэш-код используется для индексации конкретного ведра, в котором элемент помещен внутри хэш-карты, более низкий хэш приводит к более низкому индексу. Имейте в виду, что сохранившийся порядок просто очевиден: добавив другие элементы в хэш-карту, вероятно, что больше одного элемента будет помещено внутри одного и того же ведра, поэтому то, что вы видите, не гарантируется, это может быть только побочный эффект, который может возникнуть. HashMap не сортированная коллекция, и вы не должны использовать ее как таковой. TreeMap - это путь, когда вам нужны отсортированные пары.

Для Double, Float, BigInteger и String функция хэш-код менее тривиальным, таким образом, порядок не сохраняется.

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} 

- нет сортировки

Смежные вопросы