日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

hashset java 键值对_Java中的各个容器的性能对比

發布時間:2023/12/15 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hashset java 键值对_Java中的各个容器的性能对比 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java中個個容器的屬性,性能,參數對比;

Java容器的性能及屬性的對比

List:Vector,ArrayList,LinkedList

Vector:內部是數組數據結構,可以理解為加鎖的ArrayList,線程安全的,增刪,查詢都很慢。

Vector在JDK1.0版本就已經出現了,在1.2版本后出現了Collection集合,開始有集合框架,Vector改進為可以實現List接口,納入集合框架。構造函數Vector()構造一個空向量,內部數組默認初始化大小為10。Vector中的方法都是從Collection和List繼承來的。但Vector有一些特有的方法 :void addElement(E obj)

E firstElement()

E lastElement()

boolean removeElement(Object obj)

void setElementAt(E obj, int index)等…這些方法和對應不帶Element的方法功能相同。

ArrayList

ArrayList是大小可變的數組,ArrayList()構造函數默認初始化一個容量為10的空列表,如果剛開始給它開辟的內存是11,那么,它的初始化就是11的容量;

ArrayList中每一個元素都有自己的地址值,數組中存儲著這些元素的地址值,因為數組是一片連續的空間,所以在查詢某一元素的時候速度很快。但是刪除某個元素的時候,如果是刪除最后一個則很快,否則刪除的元素位置越靠前越慢,因為刪除后后面的元素都要位移前一位,查詢是根據數組的下標索引查的,所以相對于移動元素的時間很快,同樣添加元素也是一樣,越靠后越快;

LinkedList 是雙向鏈接列表數據存儲格式的,簡稱鏈表格式

鏈表中每個元素都有自己的地址,第一個元素記住第二個元素的地址,第二個元素記住第三個元素的地址,以此類推…如果想要查詢其中的某一個元素,要從第一個元素挨個做判斷,因為這些元素不是連續的,所以很慢。如果要增加一個元素,讓這個元素把地址給前一個元素,再記住后一個元素的位置即可;如果要刪除一個元素,只要它前一個元素記住它后一個元素的地址即可,所以增刪的速度很快。 增刪的速度也是相對的,LinkedList是雙向鏈表如果刪除第一個元素那是最快的,如果刪除最后一個元素也很快,同樣添加第一個元素或最后一個元素會很快.

HashSet

速度快、效率高,

不能保證元素的排列順序,順序有可能發生變化

不是同步的

集合元素可以是null,但只能放入一個null

當向HashSet集合中存入一個元素時,HashSet會調用該對象的hashCode()方法來得到該對象的hashCode值,然后根據 hashCode值來決定該對象在HashSet中存儲位置。

簡單的說,HashSet集合判斷兩個元素相等的標準是兩個對象通過equals方法比較相等,并且兩個對象的hashCode()方法返回值相 等

注意,如果要把一個對象放入HashSet中,重寫該對象對應類的equals方法,也應該重寫其hashCode()方法。其規則是如果兩個對 象通過equals方法比較返回true時,其hashCode也應該相同。另外,對象中用作equals比較標準的屬性,都應該用來計算 hashCode的值。

HashSet要求放入的對象必須實現HashCode()方法,放入的對象,是以hashcode碼作為標識的,而具有相同內容的 String對象,hashcode是一樣,所以放入的內容不能重復。但是同一個類的對象可以放入不同的實例 。

TreeSet

1、TreeSet 是二差樹實現的,Treeset中的數據是自動排好序的,不允許放入null值。

2、HashSet 是哈希表實現的,HashSet中的數據是無序的,可以放入null,但只能放入一個null,兩者中的值都不能重復,就如數據庫中唯一約束。

是一個可排序的Set,TreeSet是SortedSet接口的唯一實現類,TreeSet可以確保集合元素處于排序狀態。TreeSet支持兩種排序方式,自然排序 和定制排序,其中自然排序為默認的排序方式。向TreeSet中加入的應該是同一個類的對象。

TreeSet判斷兩個對象不相等的方式是兩個對象通過equals方法返回false,或者通過CompareTo方法比較沒有返回0

自然排序

自然排序使用要排序元素的CompareTo(Object obj)方法來比較元素之間大小關系,然后將元素按照升序排列。

Java提供了一個Comparable接口,該接口里定義了一個compareTo(Object obj)方法,該方法返回一個整數值,實現了該接口的對象就可以比較大小。

obj1.compareTo(obj2)方法如果返回0,則說明被比較的兩個對象相等,如果返回一個正數,則表明obj1大于obj2,如果是 負數,則表明obj1小于obj2。

如果我們將兩個對象的equals方法總是返回true,則這兩個對象的compareTo方法返回應該返回0

定制排序

自然排序是根據集合元素的大小,以升序排列,如果要定制排序,應該使用Comparator接口,實現 int compare(T o1,T o2)方法。

使用場景:HashSet是基于Hash算法實現的,其性能通常都優于TreeSet。我們通常都應該使用HashSet,在我們需要排序的功能時,我們才使用TreeSet。

HashSet與TreeSet的底層運行方式: TreeSet集合對象的加入過程:
TreeSet的底層是通過二叉樹來完成存儲的,無序的集合
當我們將一個對象加入treeset中,treeset會將第一個對象作為根對象,然后調用對象的compareTo方法拿第二個對象和第一個比較,當返回至=0時,說明2個對象內容相等,treeset就不把第二個對象加入集合。返回>1時,說明第二個對象大于第一個對象,將第二個對象放在右邊,返回-1時,則將第二個對象放在左邊,依次類推

HashSet集合對象的加入過程:

Hashset底層是hash值的地址,它里面存的對象是無序的。 第一個對象進入集合時,hashset會調用object類的hashcode根據對象在堆內存里的地址調用對象重寫的hashcode計算出一個hash值,然后第一個對象就進入hashset集合中的任意一個位置。

第二個對象開始進入集合,hashset先根據第二個對象在堆內存的地址調用對象的計算出一個hash值,如果第二個對象和第一個對象在堆內存里的地址是相同的,那么得到的hash值也是相同的,直接返回true,hash得到true后就不把第二個元素加入集合(這段是hash源碼程序中的操作)。如果第二個對象和第一個對象在堆內存里地址是不同的,這時hashset類會先調用自己的方法遍歷集合中的元素,當遍歷到某個元素時,調用對象的equals方法,如果相等,返回true,則說明這兩個對象的內容是相同的,hashset得到true后不會把第二個對象加入集合。

HashMap 主要用來存放鍵值對,它基于哈希表的Map接口實現,是常用的Java集合之一,數據是無序的,jdk1.8在解決哈希沖突時有了較大的變化,當鏈表長度大于閾值(默認為8)時,將鏈表轉化為紅黑樹,以減少搜索時間。

HashMap的數組

HashMap的數組的鏈表

HashMap JDK1.8 之前 HashMap 由 數組+鏈表 組成的,數組是 HashMap 的主體,鏈表則是主要為了解決哈希沖突而存在的.

HashMap的時間復雜度O(1),但是如果沖突較多,鏈表的時間復雜度是O(n),所以在JDK1.8 以后,當鏈表長度大于閾值(默認為 8)時,將鏈表轉化為紅黑樹,以減少搜索時間,紅黑樹的時間復雜度是O(log n)。 所以查詢一個HashMap數據的時間為 O(1) + O(n)或O(1) + O(log n) 平均為O(1)

總結:HashMap根據鍵的HashCode值存儲數據,根據鍵可以直接獲取它的值,具有很快的訪問速度,插入、刪除和定位元素,HashMap是最好的選擇。

TreeMap

TreeMap是基于紅黑樹實現的一個保證有序性的Map 基于紅黑樹,所以TreeMap的時間復雜度是O(log n),如果需要有排序的數據,直接存放進TreeMap中就行,TreeMap自己會給排序,不需要再寫排序代碼。

總結:TreeMap取出來的是排序后的鍵值對。插入、刪除需要維護平衡會犧牲一些效率。但如果要按自然順序或自定義順序遍歷,那么TreeMap會更好。

HashMap通過hashcode對其內容進行快速查找,而 TreeMap中所有的元素都保持著某種固定的順序,如果你需要得到一個有序的結果你就應該使用TreeMap。HashMap通常比TreeMap效率要高一些,一個是哈希表,一個是二叉樹,建議多使用HashMap,在需要排序的Map時候才用TreeMap。HashMap的查詢速度比TreeMap要快。

HashMap 數組鏈表的紅黑樹TreeMap 二叉樹的紅黑樹

LinkedHashSet 是具有可預知迭代順序的Set接口的哈希表和鏈接列表實現。此實現與HashSet的不同之處在于,后者維護著一個運行于所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,該迭代順序可為插入順序或是訪問順序。

注意,此實現不是同步的。如果多個線程同時訪問鏈接的哈希Set,而其中至少一個線程修改了該Set,則它必須保持外部同步。

LinkedHashSet:繼承于HashSet,基于LinkedHashMap來實現.底層是LinkedHashMap實現

      Set接口的一個實現.和HashSet的區別,LinkedHashSet維護一個雙重鏈接列表,定義了迭代順序可為插入順序,或者是訪問順序.

CurrentHashMap 1.7與HashMap1.7非常相似,唯一的區別就是其中的核心數據如value,以及鏈表都是volatile修飾的,保證了獲取時的可見性。

ConcurrentHashMap采用了分段鎖技術,其中Segment繼承于ReetrantLock。不會像HashTable

那樣不管是put還是get操作都需要做同步處理,理論上ConcurrentHashMap支持Segment數組數量的線程并發。

每當一個線程占用鎖訪問一個Segment時,不會影響到其他的Segment。

ArrayList、Vector、HashMap、HashSet的默認初始容量、加載因子、擴容增量

當底層實現涉及到擴容時,容器或重新分配一段更大的連續內存(如果是離散分配則不需要重新分配,離散分配都是插入新元素時動態分配內存),要將容器原來的數據全部復制到新的內存上,這無疑使效率大大降低。

加載因子的系數小于等于1,意指 即當 元素個數 超過 容量長度*加載因子的系數 時,進行擴容。

另外,擴容也是有默認的倍數的,不同的容器擴容情況不同。

List 元素是有序的、可重復

ArrayList、Vector默認初始容量為10

Vector:線程安全,但速度慢

    底層數據結構是數組結構

    加載因子為1:即當 元素個數 超過 容量長度 時,進行擴容

    擴容增量:原容量的 1倍

      如 Vector的容量為10,一次擴容后是容量為20,

當初始化給11的時候,首次內存空間就是11,然后擴容的話是22,

ArrayList:線程不安全,查詢速度快

    底層數據結構是數組結構

    擴容增量:原容量的 0.5倍+1

      如 ArrayList的容量為10,一次擴容后是容量為16

當初始化給11的時候,首次內存空間就是11,然后擴容的話是19,

Set(集) 元素無序的、不可重復。

HashSet:線程不安全,存取速度快

     底層實現是一個HashMap(保存數據),實現Set接口

     默認初始容量為16(為何是16,見下方對HashMap的描述)

     加載因子為0.75:即當 元素個數 超過 容量長度的0.75倍 時,進行擴容

     擴容增量:原容量的 1 倍

      如 HashSet的容量為16,一次擴容后是容量為32

構造方法摘要HashSet()
HashSet(int initialCapacity)
構造一個新的空 set,其底層 HashMap 實例具有指定的初始容量和默認的加載因子(0.75)。
HashSet hs=new HashSet(1);
所以可見 HashSet類,創建對象的時候是可以的制定容量的大小的 ,期中第二個就具有這個工功能。

Map是一個雙列集合

HashMap:默認初始容量為16

     (為何是16:16是2^4,可以提高查詢效率,另外,32=16<<1 -->至于詳細的原因可另行分析,或分析源代碼)

     加載因子為0.75:即當 元素個數 超過 容量長度的0.75倍 時,進行擴容

     擴容增量:原容量的 1 倍

      如 HashSet的容量為16,一次擴容后是容量為32

理論上講ArryaList的數據是線性的,LinkedList是離散的數據,LinkedList更消耗內存,但是ArrayList有個擴容機制,就是假設ArrayList 有11條數據,那么它的內存是16,所以怎么解釋?但是數據給出的是LinkedList更消耗內存:

ArrayList和LinkedList分別在64位操作系統和32位操作系統上運行的效率

未完待續...

總結

以上是生活随笔為你收集整理的hashset java 键值对_Java中的各个容器的性能对比的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。