Java源碼解析之超級接口Map
前言
我們在前面說到的無論是鏈表還是數(shù)組,都有自己的優(yōu)缺點(diǎn),數(shù)組查詢速度很快而插入很慢,鏈表在插入時表現(xiàn)優(yōu)秀但查詢無力。哈希表則整合了數(shù)組與鏈表的優(yōu)點(diǎn),能在插入和查找等方面都有不錯的速度。我們之后要分析的HashMap就是基于哈希表實(shí)現(xiàn)的,不過在JDK1.8中還引入了紅黑樹,其性能進(jìn)一步提升了。
今天我們來說一說超級接口Map。
一、接口Map
Map是基于Key-Value的數(shù)據(jù)格式,并且key值不能重復(fù),每個key對應(yīng)的value值唯一。Map的key也可以為null,但不可重復(fù)。
在看Map接口的方法前,我們先來看看Map.Entry接口。
二、接口Map.Entry
keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一個Set集合,此集合的類型為Map.Entry。
Map.Entry是Map聲明的一個內(nèi)部接口,此接口為泛型,定義為Entry<K,V>。它表示Map中的一個實(shí)體(一個key-value對)。接口中有g(shù)etKey(),getValue方法。
// 獲取對應(yīng)的key
K getKey();
// 獲取對應(yīng)的value
V getValue();
// 替換原有的value
V setValue(V value);
// 希望我們實(shí)現(xiàn)equals和hashCode
boolean equals(Object o);
int hashCode();
// 從1.8起,還提供了比較的方法,類似的方法共四個
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getKey().compareTo(c2.getKey());
}
三、一些重要的方法
// 返回當(dāng)前數(shù)據(jù)個數(shù) int size(); // 是否為空 boolean isEmpty(); // 判斷是否包含key,這里用到了key的equals方法,所以key必須實(shí)現(xiàn)它 boolean containsKey(Object key); // 判斷是否有key保存的值是value,這也基于equals方法 boolean containsValue(Object value); // 通過key獲取對應(yīng)的value值 V get(Object key); // 存入key-value V put(K key, V value); // 移除一個key-value對 V remove(Object key); // 從其他Map添加 void putAll(Map<? extends K, ? extends V> m); // 清空 void clear(); // 返回所有的key至Set集合中,因?yàn)閗ey是不可重的,Set也是不可重的 Set<K> keySet(); // 返回所有的values Collection<V> values(); // 返回key-value對到Set中 Set<Map.Entry<K, V>> entrySet(); // 希望我們實(shí)現(xiàn)equals和hashCode boolean equals(Object o); int hashCode();
四、超級實(shí)現(xiàn)類AbstractMap
對應(yīng)于AbstractCollection,AbstractMap的作用也是類似的,主要是提供一些方法的實(shí)現(xiàn),減少具體實(shí)現(xiàn)類的代碼量,可以方便繼承。下面我們看看它都實(shí)現(xiàn)了哪些方法:
在看方法之前,先來看看定義的兩個變量吧:
transient Set<K> keySet; transient Collection<V> values;
方法:
// 返回大小,這里大小基于entrySet的大小
public int size() {
return entrySet().size();
}
public boolean isEmpty() {
return size() == 0;
}
//基于entrySet操作
public boolean containsKey(Object key) {
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return true;
}
}
return false;
}
public boolean containsValue(Object value) {
//...
}
public V get(Object key) {
//...
}
public V remove(Object key) {
//...
}
public void clear() {
entrySet().clear();
}
除此之外,還提供了許多默認(rèn)的實(shí)現(xiàn)方法,我們看其中一個吧
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new AbstractSet<K>() {
public Iterator<K> iterator() {
return new Iterator<K>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public K next() {
return i.next().getKey();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object k) {
return AbstractMap.this.containsKey(k);
}
};
keySet = ks;
}
return ks;
}
除了以上的方法外,AbstractMap還實(shí)現(xiàn)了equals、hashCode、toString、clone等方法,這樣在具體實(shí)現(xiàn)時可以省去很多工作。
到此這篇關(guān)于Java源碼解析之超級接口Map的文章就介紹到這了,更多相關(guān)Java超級接口Map內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
電腦上安裝多個JDK版本時該如何自由切換(詳細(xì)圖文)
我們在學(xué)習(xí)的過程中經(jīng)常用到不同的jdk版本,那么如何在一臺電腦上同時安裝多個jdk版本并進(jìn)行切換呢,這篇文章主要給大家介紹了關(guān)于電腦上安裝多個JDK版本時該如何自由切換的相關(guān)資料,需要的朋友可以參考下2023-10-10
Java反射之類的實(shí)例對象的三種表示方式總結(jié)
下面小編就為大家?guī)硪黄狫ava反射之類的實(shí)例對象的三種表示方式總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10
java實(shí)現(xiàn)輕輕松松控制臺斗地主的示例代碼
這篇文章主要介紹了java實(shí)現(xiàn)輕輕松松控制臺斗地主,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

