1. 程式人生 > >java-hashset隨機數字放入後大小排序的假象,以及數字大小與數字範圍的關係。

java-hashset隨機數字放入後大小排序的假象,以及數字大小與數字範圍的關係。

起因

首先是因為thinking in java的一個例子(一個存放int的set集合):
這裡寫圖片描述
但是與他期待的output不一致:
這裡寫圖片描述
出現了從小到大的順序排列輸出。
仔細看看果然沒什麼差別(網上看到原因是jdk版本不一致,hashmap的hash演算法不一致)

在網上找到了存放資料的原理:

簡要概括就是因為hashset裡面存放的是hashmap,數字是放進了hashmap的entry的key之中。如何遍歷是通過迭代器,迭代器遍歷的其實是key的迭代物件,也就是遍歷了一遍hashmap的key。

public Iterator<E> iterator() {
        return
map.keySet().iterator(); }
    public static int hashCode(int value) {
        return value;
    }

瞭解hashmap的放入資料的同學應該知道,那個entry陣列是根據hashcode排列的,所以比如說是10個數字一到十,那麼那個陣列的hashcode就是一到十,所以從頭開始遍歷就是那個從小到大的順序。

但是發生了奇怪的事情:

這裡寫圖片描述

這裡寫圖片描述

一百個數字的時候0-100正常排序但是0-300又是亂了。

個人理解是:是不是可以這樣理解,100個100以內的數字正好差不多100大小的陣列排好 不產生碰撞,但是100個300以內的會發生碰撞,然後陣列大小擴容到一定程度也放得下,所以陣列不會繼續擴容。

所以100個300以內的數字,陣列長度可能是100/0.75 大概是125左右 因為是從16開始翻倍增長的所以長度應該是128,與下圖這個126數字相符。因此我猜測擴容到128就不會擴容了。之後放入的數字可能就會碰撞,就像138,然後不會擴容,因此會像下面的數字一樣存放。比128大的也可能不碰撞,就像133,134。
這裡寫圖片描述
3
4
133 % 128 = 5
134 % 128 = 6
7
9
10 (138 % 128 = 10)碰撞了。

有高人理解可以留言交流。