導航:首頁 > 編程語言 > javamap的底層

javamap的底層

發布時間:2023-05-28 03:10:47

1. java中,map分為哪些種類

您好,提問者:
Map:HashMap、TreeMap、Hashtable。
1、HashMap:線程不安全,鍵、值不允許為null。
2、Hashtable:線程安全,鍵、值允許為null。
3、TreeMap:線程不安全、鍵、值不允許為null,底層二叉樹。

2. java里map底層是通過什麼實現的隊列和鍵值有什麼區別

它的實現原理有些類似於二維數組,但是新的HashMap集合,是採用非同步方式來實現的,它的效率較高!老的TableMap是同步實現的的,所以現在不推薦用這個,有時間可以看看底層代碼,一看就明白了,很簡單的

3. java中,HashMap底層數據結構是什麼

jdk1.8以前是數組+連表,jdk1.8以後是數組+連散局滲表+紅黑樹,數組長度超過8會變成紅黑臘派樹,小於8依然是沖脊數組+連表

4. JAVA中的HASHSET和HASHMap的底層實現是怎樣的大致講一下。

HASHMAP是根據HASH演算法儲存數據的集合類,每一個存入其中的對象都有一個特定的哈希值!當我們新建一個HashMap對象,如果不給定它的大小,其默認為16,就相當與下面新建了編號為0到15的數組(鏈表數組)。以默認HashMap為例,put一個對象時,首先得到他的哈希值,在與十五相除得到余埋差指數,找到與余數相同編號的數組插入其中!HASHSET就是沒有value值的HASHMAP,你可以新建一個HASHSET,插入彎配0到15,絕對以0到15的順序列印慶清。

5. Java中HashMap和TreeMap的區別深入理解

首先介紹一下什麼是Map。在數組中我們是通過數組下標來對其內容索引的,而在Map中我們通過對象來對對象進行索引,用來索引的對象叫做key,其對應的對象叫做value

首先介紹一下什麼是Map。在數組中我們是通過數組下標來對其內容索引的,而在Map中我們通過對象來對對象進行索引,用來索引的對象叫做key,其對應的對象叫做value。這就是我們平時說的鍵值對。

HashMap通過hashcode對其內容進行快速查找,而
TreeMap中所有的元素都保持著某種固定的順序,如果你需要得到一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。

HashMap 非線程安全 TreeMap 非線程安全

線程安全

在Java里,線程安全一般體現在兩個方面:

1、多個thread對同一個java實例的訪問(read和modify)不會相互干擾,它主要體現在關鍵字synchronized。如ArrayList和Vector,HashMap和Hashtable

(後者每個方法前都有synchronized關鍵字)。如果你在interator一個List對象時,其它線程remove一個element,問題就出現了。

2、每個線程都有自己的欄位,而不會在多個線程之間共享。它主要體現在java.lang.ThreadLocal類,而沒有Java關鍵字支持,如像static、transient那樣。

1.AbstractMap抽象類和SortedMap介面

AbstractMap抽象類:(HashMap繼承AbstractMap)覆蓋了equals()和hashCode()方法以確保兩個相等映射返回相同的哈希碼。如果兩個映射大小相等、包含同樣的鍵且每個鍵在這兩個映射中對應的值都相同,則這兩個映射相等。映射的哈希碼是映射元素哈希碼的總和,其中每個元素是Map.Entry介面的一個實現。因此,不論映射內部順序如何,兩個相等映射會報告相同的哈希碼。

SortedMap介面:(TreeMap繼承自SortedMap)它用來保持鍵的有序順序。SortedMap介面為映像的視圖(子集),包括兩個端點提供了訪問方法。除了排序是作用於映射的鍵以外,處理SortedMap和處理SortedSet一樣。添加到SortedMap實現類的元素必須實現Comparable介面,否則您必須給它的構造函數提供一個Comparator介面的實現。TreeMap類是它的唯一一份實現。

2.兩種常規Map實現

HashMap:基於哈希表實現。使用HashMap要求添加的鍵類明確定義了hashCode()和equals()[可以重寫hashCode()和equals()],為了優化HashMap空間的使用,您可以調優初始容量和負載因子。

(1)HashMap(): 構建一個空的哈希映像
(2)HashMap(Map m): 構建一個哈希映像,並且添加映像m的所有映射

(3)HashMap(int initialCapacity): 構建一個擁有特定容量的空的哈希映像
(4)HashMap(int
initialCapacity, float loadFactor): 構建一個擁有特定容量和載入因子的空的哈希映像

TreeMap:基於紅黑樹實現。TreeMap沒有調優選項,因為該樹總處於平衡狀態。
(1)TreeMap():構建一個空的映像樹

(2)TreeMap(Map m): 構建一個映像樹,並且添加映像m中所有元素
(3)TreeMap(Comparator c):
構建一個映像樹,並且使用特定的比較器對關鍵字進行排序
(4)TreeMap(SortedMap s):
構建一個映像樹,添加映像樹s中所有映射,並且使用與有序映像s相同的比較器排序

3.兩種常規Map性能

HashMap:適用於在Map中插入、刪除和定位元素。
Treemap:適用於按自然順序或自定義順序遍歷鍵(key)。

4.總結

HashMap通常比TreeMap快一點(樹和哈希表的數據結構使然),建議多使用HashMap,在需要排序的Map時候才用TreeMap。

復制代碼
代碼如下:

import java.util.HashMap;
import
java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import java.util.TreeMap;
public class HashMaps {
public static void
main(String[] args) {
Map<String, String> map = new HashMap<String,
String>();
map.put("a", "aaa");
map.put("b", "bbb");
map.put("c",
"ccc");
map.put("d", "ddd");
Iterator<String> iterator =
map.keySet().iterator();
while (iterator.hasNext()) {
Object key =
iterator.next();
System.out.println("map.get(key) is :" + map.get(key));

}
// 定義HashTable,用來測試
Hashtable<String, String> tab = new
Hashtable<String, String>();
tab.put("a", "aaa");
tab.put("b",
"bbb");
tab.put("c", "ccc");
tab.put("d", "ddd");

Iterator<String> iterator_1 = tab.keySet().iterator();
while
(iterator_1.hasNext()) {
Object key = iterator_1.next();

System.out.println("tab.get(key) is :" + tab.get(key));
}

TreeMap<String, String> tmp = new TreeMap<String, String>();

tmp.put("a", "aaa");
tmp.put("b", "bbb");
tmp.put("c", "ccc");

tmp.put("d", "cdc");
Iterator<String> iterator_2 =
tmp.keySet().iterator();
while (iterator_2.hasNext()) {
Object key =
iterator_2.next();
System.out.println("tmp.get(key) is :" + tmp.get(key));

}
}
}

運行結果如下:
map.get(key) is :ddd

map.get(key) is :bbb
map.get(key) is :ccc
map.get(key) is :aaa

tab.get(key) is :bbb
tab.get(key) is :aaa
tab.get(key) is :ddd

tab.get(key) is :ccc
tmp.get(key) is :aaa
tmp.get(key) is :bbb

tmp.get(key) is :ccc
tmp.get(key) is :cdc

HashMap的結果是沒有排序的,而TreeMap輸出的結果是排好序的。
下面就要進入本文的主題了。先舉個例子說明一下怎樣使用HashMap:

復制代碼
代碼如下:

import java.util.*;
public class Exp1 {

public static void main(String[] args){
HashMap h1=new HashMap();

Random r1=new Random();
for (int i=0;i<1000;i++){
Integer t=new
Integer(r1.nextInt(20));
if (h1.containsKey(t))

((Ctime)h1.get(t)).count++;
else
h1.put(t, new Ctime());
}

System.out.println(h1);
}
}
class Ctime{
int count=1;

public String toString(){
return Integer.toString(count);
}
}

在HashMap中通過get()來獲取value,通過put()來插入value,ContainsKey()則用來檢驗對象是否已經存在。可以看出,和ArrayList的操作相比,HashMap除了通過key索引其內容之外,別的方面差異並不大。

前面介紹了,HashMap是基於HashCode的,在所有對象的超類Object中有一個HashCode()方法,但是它和equals方法一樣,並不能適用於所有的情況,這樣我們就需要重寫自己的HashCode()方法。下面就舉這樣一個例子:

復制代碼
代碼如下:

import java.util.*;
public class Exp2 {

public static void main(String[] args){
HashMap h2=new HashMap();

for (int i=0;i<10;i++)
h2.put(new Element(i), new Figureout());

System.out.println("h2:");
System.out.println("Get the result for
Element:");
Element test=new Element(5);
if (h2.containsKey(test))

System.out.println((Figureout)h2.get(test));
else

System.out.println("Not found");
}
}
class Element{
int
number;
public Element(int n){
number=n;
}
}
class
Figureout{
Random r=new Random();
boolean
possible=r.nextDouble()>0.5;
public String toString(){
if (possible)

return "OK!";
else
return "Impossible!";
}
}

在這個例子中,Element用來索引對象Figureout,也即Element為key,Figureout為value。在Figureout中隨機生成一個浮點數,如果它比0.5大,列印"OK!",否則列印"Impossible!"。之後查看Element(3)對應的Figureout結果如何。

結果卻發現,無論你運行多少次,得到的結果都是"Not found"。也就是說索引Element(3)並不在HashMap中。這怎麼可能呢?

原因得慢慢來說:Element的HashCode方法繼承自Object,而Object中的HashCode方法返回的HashCode對應於當前的地址,也就是說對於不同的對象,即使它們的內容完全相同,用HashCode()返回的值也會不同。這樣實際上違背了我們的意圖。因為我們在使用
HashMap時,希望利用相同內容的對象索引得到相同的目標對象,這就需要HashCode()在此時能夠返回相同的值。在上面的例子中,我們期望 new
Element(i) (i=5)與
Elementtest=newElement(5)是相同的,而實際上這是兩個不同的對象,盡管它們的內容相同,但它們在內存中的地址不同。因此很自然的,上面的程序得不到我們設想的結果。下面對Element類更改如下:

復制代碼
代碼如下:

class Element{
int number;
public
Element(int n){
number=n;
}
public int hashCode(){
return
number;
}
public boolean equals(Object o){
return (o instanceof
Element) && (number==((Element)o).number);
}
}

在這里Element覆蓋了Object中的hashCode()和equals()方法。覆蓋hashCode()使其以number的值作為
hashcode返回,這樣對於相同內容的對象來說它們的hashcode也就相同了。而覆蓋equals()是為了在HashMap判斷兩個key是否相等時使結果有意義(有關重寫equals()的內容可以參考我的另一篇文章《重新編寫Object類中的方法》)。修改後的程序運行結果如下:

h2:
Get the result for Element:
Impossible!

請記住:如果你想有效的使用HashMap,你就必須重寫在其的HashCode()。
還有兩條重寫HashCode()的原則:

[list=1]

不必對每個不同的對象都產生一個唯一的hashcode,只要你的HashCode方法使get()能夠得到put()放進去的內容就可以了。即"不為一原則"。

生成hashcode的演算法盡量使hashcode的值分散一些,不要很多hashcode都集中在一個范圍內,這樣有利於提高HashMap的性能。即"分散原則"。至於第二條原則的具體原因,有興趣者可以參考Bruce
Eckel的《Thinking in Java》,在那裡有對HashMap內部實現原理的介紹,這里就不贅述了。

掌握了這兩條原則,你就能夠用好HashMap編寫自己的程序了。不知道大家注意沒有,java.lang.Object中提供的三個方法:clone(),equals()和hashCode()雖然很典型,但在很多情況下都不能夠適用,它們只是簡單的由對象的地址得出結果。這就需要我們在自己的程序中重寫它們,其實java類庫中也重寫了千千萬萬個這樣的方法。利用面向對象的多態性——覆蓋,Java的設計者很優雅的構建了Java的結構,也更加體現了Java是一門純OOP語言的特性。

6. java裡面的map是什麼

java為數據結構中的映射定義了一個介面java.util.Map
Map主要用於存儲健值對,根據鍵得到值,因此不允許鍵重復(重復了覆蓋了),但允許值重復。

7. Java 中Map與數組的比較

1、數組特點高效、保存基本類型,集合帶array的底層由數組實現,還有一部分由鏈表或者樹
2、數組大小固定(巨大缺點,內存中一定連續),集合各種實現吧!
3、數組只能放一種類型,集合不考慮泛型可以存很多類型。
4、集合放原始類型其實是通過裝箱拆箱來實現的,說白了以前原生類型只能用數組,現在集合也可以了。因為這個改進,所以現在基本上除了性能外,均推薦使用集合。

8. Java中HashMap和TreeMap的區別深入理解

HashMap底層是用數組做的,TreeMap是基於樹做的
這么做的結果就是HashMap的數據在不停的添加的時候效率會比較低,而對於查找的效率是比較快的,TreeMap對於添加的效率是比較高的但是對於查找的效率要相對比較低一些

這里簡單從底層說一下,我就不從具體的實現上說,只從數據結構和大致的原理上來補充一下我的答案。
HashMap這個類在存儲的時候,首先根據key來計算機將要存儲的key-value映射對存儲在數組的什麼位置上,當計算出位置後就把這個映射對存儲到這個位置上。當讀取的時候,首先根據key來計算出一個位置來,到數組的相應的位置上去讀取數據,如果沒有數據,則表示此Map中不存在該映射對,若存在則直接返回。說到這里就可以解釋一下為什麼對於不停地存儲的效率相對比較低了,首先在初始化的時候對於數組的長度給了一個初始的長度,當往這裡面添加數據達到一定的程度的時候就沒法繼續添加數據了,繼續添加數據的沖突就會增大,或者沒法添加數據(這里有一個衡量的量就是裝填因子,是指這個數組中的添加的數據的個數和數組長度的比值,在java中比較合理的裝填因子數是0.75),當數據添加到這個程度的時候不能不讓用戶繼續添加數據吧,總得解決繼續添加數據的問題啊,於是提出了解決方案,即開一個更大的數組,把當前上的每一個數據重新在更大的數組上計算位置,並把數據復制過去,這樣完成的數組的擴大,看完這個我們知道,這個過程是很耗時的,所以說對於不停的存儲數據時效率是比較低的。這里有沒有一個稍微好一點的解決方案或者說不需要進行數組的擴大嗎,我們能不能一開始在初始化的時候就把數組的空間開辟的足夠大,這樣就不用在存儲的過程進行復制了,可以嗎,答案是肯定的,java給我們提供了這個在初始化的時候的方式。但是,也是有問題的那就是我們的數據不夠多,就會造成空間的浪費。有沒有一個速度即快又不浪費空間的方式呢,解決方案也有一個,那就是在開始的時候我們就能很好的預測數據的規模,這樣我們在開始的時候按照相應的規模進行初始化,這樣就很好了,實際中我們是不能很好的預測這個規模的。於是對於這種情況提出了下一個解決方案TreeMap。
TreeMap是一個基於樹的存儲結構,學過數據結構的應該知道,樹的實現方式是基於指針實現的,在Java中是用引用模擬實現的,這里大家都知道,其實樹的讀取效率並不低,這里是相對於數組的順序查找來說的,但是與HashMap的查找方式相比就有了差距,HashMap是上來先問你在哪,直接就去取數據了,TreeMap需要遍歷,也就是需要挨個詢問你是我要的東西嗎,對比一下,是就返回,不是就繼續查找,於是查找的效率就低了,但是它解決了HashMap數組擴大的時候的效率問題,就是新添加的數據可以往裡面添加,不會出現復制的情況,這里就是由於模擬的指針的緣故實現的。
其實從總體來說這兩個各有利弊,我們在使用的時候需要根據實際的需要來選擇相應的類。

9. java中的Map有什麼用呢

Map的介面Map---實現Map
Map.Entry--Map的內部類,描述Map中的按鍵/數值對。
SortedMap---擴展Map,使按鍵保持升序排列
下面以HashMap為例。
public static void main(String args[]){HashMap hashmap = new HashMap();
hashmap.put("Item0", "Value0");
hashmap.put("Item1", "Value1");
hashmap.put("Item2", "Value2");
hashmap.put("Item3", "Value3");
Set set = hashmap.entrySet();
Iterator iterator = set.iterator();
while (iterator.hasNext(){Map.Entry mapentry = (Map.Entry) iterator.next();
System.out.println(mapentry.getkey() + "/" + mapentry.getValue());}}注意,這里Map的按鍵必須是唯一的,比如說不能有兩個按鍵都為null。
如果用過它,就會知道它的用處了。
資料:java.util 中的集合類包含 Java 中某些最常用的類。 最常用的集合類是 List 和 Map。 List 的具體實現包括 ArrayList 和 Vector,它們是可變大小的列表,比較適合構建、存儲和操作任何類型對象的元素列表。 List 適用於按數值索引訪問元素的情形。Map 提供了一個更通用的元素存儲方法。 Map 集合類用於存儲元素對(稱作「鍵」和「值」),其中每個鍵映射到一個值。 從概念上而言,您可以將 List 看作是具有數值鍵的 Map。 而實際上,除了 List 和 Map 都在定義 java.util 中外,兩者並沒有直接的聯系。本文將著重介紹核心 Java 發行套件中附帶的 Map,同時還將介紹如何採用或實現更適用於您應用程序特定數據的專用 Map。了解Map 介面和方法Java 核心類中有很多預定義的 Map 類。 在介紹具體實現之前,我們先介紹一下 Map 介面本身,以便了解所有實現的共同點。 Map 介面定義了四種類型的方法,每個 Map 都包含這些方法。 下面,我們從兩個普通的方法(表1)開始對這些方法加以介紹。表1: 覆蓋的方法。 我們將這 Object 的這兩個方法覆蓋,以正確比較 Map 對象的等價性。equals(Object o)比較指定對象與此 Map 的等價性hashCode()返回此 Map 的哈希碼Map 構建Map 定義了幾個用於插入和刪除元素的變換方法(表2)。表2: Map 更新方法: 可以更改 Map 內容。clear()從Map 中刪除所有映射remove(Object key)從Map 中刪除鍵和關聯的值put(Object key, Object value)將指定值與指定鍵相關聯clear()從Map 中刪除所有映射putAll(Map t)將指定 Map 中的所有映射復制到此 map盡管您可能注意到,縱然假設忽略構建一個需要傳遞給 putAll() 的 Map 的開銷,使用 putAll() 通常也並不比使用大量的 put() 調用更有效率,但 putAll() 的存在一點也不稀奇。 這是因為,putAll() 除了迭代 put() 所執行的將每個鍵值對添加到 Map 的演算法以外,還需要迭代所傳遞的 Map 的元素。 但應注意,putAll() 在添加所有元素之前可以正確調整 Map 的大小,因此如果您未親自調整 Map 的大小(我們將對此進行簡單介紹),則 putAll() 可能比預期的更有效。查看Map迭代Map 中的元素不存在直接了當的方法。 如果要查詢某個 Map 以了解其哪些元素滿足特定查詢,或如果要迭代其所有元素(無論原因如何),則您首先需要獲取該 Map 的「視圖」。 有三種可能的視圖(參見表3)所有鍵值對 — 參見 entrySet()所有鍵 — 參見 keySet()所有值 — 參見 values()前兩個視圖均返回 Set 對象,第三個視圖返回 Collection 對象。 就這兩種情況而言,問題到這里並沒有結束,這是因為您無法直接迭代 Collection 對象或 Set 對象。要進行迭代,您必須獲得一個 Iterator 對象。 因此,要迭代 Map 的元素,必須進行比較煩瑣的編碼Iterator keyValuePairs = aMap.entrySet().iterator();Iterator keys = aMap.keySet().iterator();Iterator values = aMap.values().iterator();值得注意的是,這些對象(Set、Collection 和 Iterator)實際上是基礎 Map 的視圖,而不是包含所有元素的副本。 這使它們的使用效率很高。 另一方面,Collection 或 Set 對象的 toArray() 方法卻創建包含 Map 所有元素的數組對象,因此除了確實需要使用數組中元素的情形外,其效率並不高。我運行了一個小測試(隨附文件中的 Test1),該測試使用了 HashMap,並使用以下兩種方法對迭代 Map 元素的開銷進行了比較:int mapsize = aMap.size();Iterator keyValuePairs1 = aMap.entrySet().iterator();for (int i = 0; i < mapsize; i++){ Map.Entry entry = (Map.Entry) keyValuePairs1.next(); Object key = entry.getKey(); Object value = entry.getValue(); ...}Object[] keyValuePairs2 = aMap.entrySet().toArray();for (int i = 0; i < rem; i++) {{ Map.Entry entry = (Map.Entry) keyValuePairs2[i]; Object key = entry.getKey();
Profilers in Oracle JDeveloperOracle JDeveloper 包含一個嵌入的監測器,它測量內存和執行時間,使您能夠快速識別代碼中的瓶頸。 我曾使用 Jdeveloper 的執行監測器監測 HashMap 的 containsKey() 和 containsValue() 方法,並很快發現 containsKey() 方法的速度比 containsValue() 方法慢很多(實際上要慢幾個數量級!)。 (參見圖1 和圖2,以及隨附文件中的 Test2 類)。 Object value = entry.getValue(); ...}此測試使用了兩種測量方法: 一種是測量迭代元素的時間,另一種測量使用 toArray 調用創建數組的其他開銷。 第一種方法(忽略創建數組所需的時間)表明,使用已從 toArray 調用中創建的數組迭代元素的速度要比使用 Iterator 的速度大約快 30%-60%。 但如果將使用 toArray 方法創建數組的開銷包含在內,則使用 Iterator 實際上要快 10%-20%。 因此,如果由於某種原因要創建一個集合元素的數組而非迭代這些元素,則應使用該數組迭代元素。 但如果您不需要此中間數組,則不要創建它,而是使用 Iterator 迭代元素。表3: 返回視圖的 Map 方法: 使用這些方法返回的對象,您可以遍歷 Map 的元素,還可以刪除 Map 中的元素。entrySet()返回Map 中所包含映射的 Set 視圖。 Set 中的每個元素都是一個 Map.Entry 對象,可以使用 getKey() 和 getValue() 方法(還有一個 setValue() 方法)訪問後者的鍵元素和值元素keySet()返回Map 中所包含鍵的 Set 視圖。 刪除 Set 中的元素還將刪除 Map 中相應的映射(鍵和值)values()返回map 中所包含值的 Collection 視圖。 刪除 Collection 中的元素還將刪除 Map 中相應的映射(鍵和值)訪問元素表4 中列出了 Map 訪問方法。Map 通常適合按鍵(而非按值)進行訪問。 Map 定義中沒有規定這肯定是真的,但通常您可以期望這是真的。 例如,您可以期望 containsKey() 方法與 get() 方法一樣快。 另一方面,containsValue() 方法很可能需要掃描 Map 中的值,因此它的速度可能比較慢。表4: Map 訪問和測試方法: 這些方法檢索有關 Map 內容的信息但不更改 Map 內容。get(Object key)返回與指定鍵關聯的值containsKey(Object key)如果Map 包含指定鍵的映射,則返回 truecontainsValue(Object value)如果此 Map 將一個或多個鍵映射到指定值,則返回 trueisEmpty()如果Map 不包含鍵-值映射,則返回 truesize()返回Map 中的鍵-值映射的數目對使用 containsKey() 和 containsValue() 遍歷 HashMap 中所有元素所需時間的測試表明,containsValue() 所需的時間要長很多。 實際上要長幾個數量級! (參見圖1 和圖2,以及隨附文件中的 Test2)。 因此,如果 containsValue() 是應用程序中的性能問題,它將很快顯現出來,並可以通過監測您的應用程序輕松地將其識別。 這種情況下,我相信您能夠想出一個有效的替換方法來實現 containsValue() 提供的等效功能。 但如果想不出辦法,則一個可行的解決方案是再創建一個 Map,並將第一個 Map 的所有值作為鍵。

10. java中的set和map的內部實現細節是什麼(就像ArrayList是Object數組,LinkedList是鏈表),越詳細越好。

一個不包含重復元素的 collection。更確切地講,set 不包含滿足 e1.equals(e2) 的元素對 e1 和 e2,並且最多包含一個 null 元素。正如其名稱所暗示的,此介面模仿了數學上的 set 抽象。

在所有構造方法以及 add、equals 和 hashCode 方法的協定上,Set 介面還加入了其他規定,這些規定超出了從 Collection 介面所繼承的內容。出於方便考慮,它還包括了其他繼承方法的聲明(這些聲明的規范已經專門針對 Set 介面進行了修改,但是沒有包含任何其他的規定)。

對這些構造方法的其他規定是(不要奇怪),所有構造方法必須創建一個不包含重復元素的 set(正如上面所定義的)。

註:如果將可變對象用作 set 元素,那麼必須極其小心。如果對象是 set 中某個元素,以一種影響 equals 比較的方式改變對象的值,那麼 set 的行為就是不確定的。此項禁止的一個特殊情況是不允許某個 set 包含其自身作為元素。

某些 set 實現對其所包含的元素有所限制。例如,某些實現禁止 null 元素,而某些則對其元素的類型所有限制。試圖添加不合格的元素會拋出未經檢查的異常,通常是 NullPointerException 或 ClassCastException。試圖查詢不合格的元素是否存在可能會拋出異常,也可能簡單地返回 false;某些實現會採用前一種行為,而某些則採用後者。概括地說,試圖對不合格元素執行操作時,如果完成該操作後不會導致在 set 中插入不合格的元素,則該操作可能拋出一個異常,也可能成功,這取決於實現的選擇。此介面的規范中將這樣的異常標記為「可選」。
public interface Map<K,V>將鍵映射到值的對象。一個映射不能包含重復的鍵;每個鍵最多隻能映射到一個值。

此介面取代 Dictionary 類,後者完全是一個抽象類,而不是一個介面。

Map 介面提供三種collection 視圖,允許以鍵集、值集或鍵-值映射關系集的形式查看某個映射的內容。映射順序 定義為迭代器在映射的 collection 視圖上返回其元素的順序。某些映射實現可明確保證其順序,如 TreeMap 類;另一些映射實現則不保證順序,如 HashMap 類。

註:將可變對象用作映射鍵時必須格外小心。當對象是映射中某個鍵時,如果以影響 equals 比較的方式更改了對象的值,則映射的行為將是不確定的。此項禁止的一種特殊情況是不允許某個映射將自身作為一個鍵包含。雖然允許某個映射將自身作為值包含,但請格外小心:在這樣的映射上 equals 和 hashCode 方法的定義將不再是明確的。

所有通用的映射實現類應該提供兩個「標準的」構造方法:一個 void(無參數)構造方法,用於創建空映射;一個是帶有單個 Map 類型參數的構造方法,用於創建一個與其參數具有相同鍵-值映射關系的新映射。實際上,後一個構造方法允許用戶復制任意映射,生成所需類的一個等價映射。盡管無法強制執行此建議(因為介面不能包含構造方法),但是 JDK 中所有通用的映射實現都遵從它。

此介面中包含的「破壞」方法可修改其操作的映射,如果此映射不支持該操作,這些方法將拋出 UnsupportedOperationException。如果是這樣,那麼在調用對映射無效時,這些方法可以(但不要求)拋出 UnsupportedOperationException。例如,如果某個不可修改的映射(其映射關系是「重疊」的)為空,則對該映射調用 putAll(Map) 方法時,可以(但不要求)拋出異常。

某些映射實現對可能包含的鍵和值有所限制。例如,某些實現禁止 null 鍵和值,另一些則對其鍵的類型有限制。嘗試插入不合格的鍵或值將拋出一個未經檢查的異常,通常是 NullPointerException 或 ClassCastException。試圖查詢是否存在不合格的鍵或值可能拋出異常,或者返回 false;某些實現將表現出前一種行為,而另一些則表現後一種。一般來說,試圖對不合格的鍵或值執行操作且該操作的完成不會導致不合格的元素被插入映射中時,將可能拋出一個異常,也可能操作成功,這取決於實現本身。這樣的異常在此介面的規范中標記為「可選」。

此介面是 Java Collections Framework 的成員。

Collections Framework 介面中的很多方法是根據 equals 方法定義的。例如,containsKey(Object key) 方法的規范中寫道:「當且僅當此映射包含針對滿足 (key==null ? k==null : key.equals(k)) 的鍵 k 的映射關系時,返回 true」。不 應將此規范解釋為:調用具有非空參數 key 的 Map.containsKey 將導致對任意的鍵 k 調用 key.equals(k)。實現可隨意進行優化,以避免調用 equals,例如,可首先比較兩個鍵的哈希碼(Object.hashCode() 規范保證哈希碼不相等的兩個對象不會相等)。一般來說,只要實現者認為合適,各種 Collections Framework 介面的實現可隨意利用底層 Object 方法的指定行為。

閱讀全文

與javamap的底層相關的資料

熱點內容
伺服器端渲染的數據怎麼爬 瀏覽:163
壓縮空氣噴射器 瀏覽:488
python提高效率 瀏覽:796
華為文件管理怎麼樣輸入解壓碼 瀏覽:800
深思加密狗初始化 瀏覽:566
黃金崩潰pdf 瀏覽:309
華為特定簡訊息加密 瀏覽:375
微機原理與單片機技術李精華答案 瀏覽:816
pic12c508單片機 瀏覽:309
androidgps調用 瀏覽:226
金文編pdf 瀏覽:445
14乘87減147的簡便演算法 瀏覽:473
怎麼創建edu文件夾 瀏覽:721
演算法的基礎問題 瀏覽:256
蘋果手機怎麼選擇app支付 瀏覽:856
訪問加密伺服器失敗怎麼回事 瀏覽:439
程序員每天跑步5公里 瀏覽:789
黨員對程序員有幫助么 瀏覽:550
慢跑穿壓縮衣還是緊身衣 瀏覽:214
什麼伺服器引擎最好 瀏覽:497