Map集合:
Map接口
???? Map與List、Set接口不同,它是由一系列鍵值對組成的集合,提供了key到Value的映射。同時它也沒有繼承Collection。在Map中它保證了key與value之間的一一對應關系。也就是說一個key對應一個value,所以它不能存在相同的key值,當然value值可以相同。
1.HashMap
????? 以哈希表數據結構實現,查找對象時通過哈希函數計算其位置,它是為快速查詢而設計的,其內部定義了一個hash表數組(Entry[] table),元素會通過哈希轉換函數將元素的哈希地址轉換成數組中存放的索引,如果有沖突,則使用散列鏈表的形式將所有相同哈希地址的元素串起來,可能通過查看HashMap.Entry的源碼它是一個單鏈表結構。
2.LinkedHashMap
???? LinkedHashMap是HashMap的一個子類,它保留插入的順序,如果需要輸出的順序和輸入時的相同,那么就選用LinkedHashMap。
???? LinkedHashMap是Map接口的哈希表和鏈接列表實現,具有可預知的迭代順序。此實現提供所有可選的映射操作,并允許使用null值和null鍵。此類不保證映射的順序,特別是它不保證該順序恒久不變。
???? LinkedHashMap實現與HashMap的不同之處在于,后者維護著一個運行于所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,該迭代順序可以是插入順序或者是訪問順序。
???? 根據鏈表中元素的順序可以分為:按插入順序的鏈表,和按訪問順序(調用get方法)的鏈表。默認是按插入順序排序,如果指定按訪問順序排序,那么調用get方法后,會將這次訪問的元素移至鏈表尾部,不斷訪問可以形成按訪問順序排序的鏈表。
???? 注意,此實現不是同步的。如果多個線程同時訪問鏈接的哈希映射,而其中至少一個線程從結構上修改了該映射,則它必須保持外部同步。
???? 由于LinkedHashMap需要維護元素的插入順序,因此性能略低于HashMap的性能,但在迭代訪問Map里的全部元素時將有很好的性能,因為它以鏈表來維護內部順序。
3.TreeMap
???? TreeMap 是一個有序的key-value集合,非同步,基于紅黑樹(Red-Black tree)實現,每一個key-value節點作為紅黑樹的一個節點。TreeMap存儲時會進行排序的,會根據key來對key-value鍵值對進行排序,其中排序方式也是分為兩種,一種是自然排序,一種是定制排序,具體取決于使用的構造方法。
自然排序:TreeMap中所有的key必須實現Comparable接口,并且所有的key都應該是同一個類的對象,否則會報ClassCastException異常。
定制排序:定義TreeMap時,創建一個comparator對象,該對象對所有的treeMap中所有的key值進行排序,采用定制排序的時候不需要TreeMap中所有的key必須實現Comparable接口。
TreeMap判斷兩個元素相等的標準:兩個key通過compareTo()方法返回0,則認為這兩個key相等。
如果使用自定義的類來作為TreeMap中的key值,且想讓TreeMap能夠良好的工作,則必須重寫自定義類中的equals()方法,TreeMap中判斷相等的標準是:兩個key通過equals()方法返回為true,并且通過compareTo()方法比較應該返回為0。
以下基于JDK1.9
public interface Map<K,V>
This interface takes the place of the?Dictionary
?class, which was a totally abstract class rather than an interface.
一個將鍵映射到值的對象。地圖不能包含重復的鍵;每個鍵最多只能映射到一個值。
這個接口取代了Dictionary類,它是一個完全抽象的類,而不是一個接口。
The?Map
?interface provides three?collection views, which allow a map's contents to be viewed as a set of keys, collection of values, or set of key-value mappings. The?orderof a map is defined as the order in which the iterators on the map's collection views return their elements. Some map implementations, like the?TreeMap
?class, make specific guarantees as to their order; others, like the?HashMap
?class, do not.
Map接口提供三個托收視圖,允許將Map的內容視為一組鍵、值集合或鍵值映射集。映射的順序是指映射集合視圖上的迭代器返回它們的元素的順序。一些映射實現,如TreeMap類,對它們的順序做出具體的保證;其他的,如HashMap類,則沒有。
Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects?equals
?comparisons while the object is a key in the map. A special case of this prohibition is that it is not permissible for a map to contain itself as a key. While it is permissible for a map to contain itself as a value, extreme caution is advised: the?equals
?and?hashCode
?methods are no longer well defined on such a map.
注意:如果可變對象被用作map鍵,必須執行非常小心的操作。如果一個對象的值發生了改變,而對象是map中的鍵,那么就不會指定映射的行為。這條禁令的一個特例是,地圖不允許將自己作為一個密鑰。雖然可以允許map將自身作為一個值來包含,但是要特別注意:在這樣的映射中,equals和hashCode方法不再很好地定義。
All general-purpose map implementation classes should provide two "standard" constructors: a void (no arguments) constructor which creates an empty map, and a constructor with a single argument of type?Map
, which creates a new map with the same key-value mappings as its argument. In effect, the latter constructor allows the user to copy any map, producing an equivalent map of the desired class. There is no way to enforce this recommendation (as interfaces cannot contain constructors) but all of the general-purpose map implementations in the JDK comply.
所有通用的Map實現類都應該提供兩個“標準”構造器:一個void(無參數)構造器,它創建一個空的映射,一個構造函數帶有一個類型映射的單一參數,它創建了一個新的映射,它的鍵值映射和它的參數一樣。實際上,后者的構造函數允許用戶復制任何映射,生成所需類的等效映射。沒有辦法強制執行這個建議(因為接口不能包含構造函數),但是JDK中的所有通用映射實現都遵從了。
The "destructive" methods contained in this interface, that is, the methods that modify the map on which they operate, are specified to throwUnsupportedOperationException
?if this map does not support the operation. If this is the case, these methods may, but are not required to, throw an?UnsupportedOperationException
?if the invocation would have no effect on the map. For example, invoking the?putAll(Map)
?method on an unmodifiable map may, but is not required to, throw the exception if the map whose mappings are to be "superimposed" is empty.
此接口中包含的“破壞性”方法,即修改地圖的方法操作,指定throwUnsupportedOperationException如果這張地圖不支持的操作。如果是這樣的話,這些方法可能,但不需要,拋出UnsupportedOperationException如果調用方式在地圖上沒有影響。例如,在不可修改的映射上調用putAll(Map)方法,但不需要,如果映射為“疊加”的映射為空,則拋出異常。
Some map implementations have restrictions on the keys and values they may contain. For example, some implementations prohibit null keys and values, and some have restrictions on the types of their keys. Attempting to insert an ineligible key or value throws an unchecked exception, typically?NullPointerException
?or?ClassCastException
. Attempting to query the presence of an ineligible key or value may throw an exception, or it may simply return false; some implementations will exhibit the former behavior and some will exhibit the latter. More generally, attempting an operation on an ineligible key or value whose completion would not result in the insertion of an ineligible element into the map may throw an exception or it may succeed, at the option of the implementation. Such exceptions are marked as "optional" in the specification for this interface.
有些映射實現對它們可能包含的鍵和值有限制。例如,有些實現禁止空鍵和值,有些實現對鍵的類型有限制。試圖插入一個不合格的鍵或值拋出未檢查的異常,通常是NullPointerException或ClassCastException。試圖查詢一個不合格的鍵或值的存在可能會拋出異常,或者它可能只是返回false;一些實現將展示前者的行為,而有些實現將展示后者。更一般的情況是,嘗試在不符合條件的鍵或值上執行操作,如果沒有將不符合條件的元素插入到map中,則可能會拋出異常,或者在實現的選項中可能成功。在該接口的規范中,這些異常被標記為“可選”。
Many methods in Collections Framework interfaces are defined in terms of the?equals
?method. For example, the specification for the?containsKey(Object key)
?method says: "returns?true
?if and only if this map contains a mapping for a key?k
?such that?(key==null ? k==null : key.equals(k))
." This specification should?not?be construed to imply that invoking?Map.containsKey
?with a non-null argument?key
?will cause?key.equals(k)
?to be invoked for any key?k
. Implementations are free to implement optimizations whereby the?equals
?invocation is avoided, for example, by first comparing the hash codes of the two keys. (The?Object.hashCode()
specification guarantees that two objects with unequal hash codes cannot be equal.) More generally, implementations of the various Collections Framework interfaces are free to take advantage of the specified behavior of underlying?Object
?methods wherever the implementor deems it appropriate.
集合框架接口中的許多方法都是用equals方法定義的。例如,容器鍵(Object key)方法的規范說:“如果且僅當這個映射包含一個鍵k的映射時返回true(key==null嗎?k = = null:key.equals(k))。”該規范不應被解釋為暗示調用Map。帶有非空參數鍵的容器鍵將會引起鍵.equals(k)被調用,因為任何關鍵k實現都可以自由地實現優化,從而避免相等的調用,例如,首先比較兩個鍵的散列碼。(object.hashcode()規范保證了不相等的哈希碼的兩個對象不能相等。)更廣泛地說,各種集合框架接口的實現可以自由地利用底層對象方法的指定行為,無論實現者認為它是合適的。
Some map operations which perform recursive traversal of the map may fail with an exception for self-referential instances where the map directly or indirectly contains itself. This includes the?clone()
,?equals()
,?hashCode()
?and?toString()
?methods. Implementations may optionally handle the self-referential scenario, however most current implementations do not do so.