Java Map接口及其实现类原理解析

网友投稿 211 2023-05-06

Java Map接口及其实现类原理解析

Map接口

Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value;

Map中的键值对以Entry类型的对象实例形式存在;

建(key值)不可重复,value值可以重复,一个value值可以和很多key值形成对应关系,每个建最多只能映射到一个值。

Map支持泛型,形式如:Map

Map中使用put(K key,V value)方法添加

Map接口中定义的常用方法

具体使用在实现类中讨论

int size();//获取Map集合大小(即元素数量)

boolean isEmpty();//判断是否为空

boolean containsKey(Object key);//判断是否包含某个键

boolean containsValue(Object value);//判断是否包含某个值

V get(Object key);//获取某个键对应的值

V put(K key, V value);//添加键值对(K,V)

V remove(Object key);//移除某个键对应的键值对

void putAll(Map extends K, ? extends V> m);//添加另一个Map集合

void clear();//清空所有键值对

Set keySet();//获取键的集合

Collection values();//获取值的集合

Set> entrySet();//获取键值对实体的集合

interface Entry//Map中的内部接口

HashMap

基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)除实现了Map接口外还实现了Cloneable,Serializable,继承了AbstractMap抽象类

此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

特点:

键无序,唯一,类似于Set集合

值有序,可重复,类似于List

底层数据结构是哈希表,保证键唯一

允许键为null,值为null

// HashMap hm = new HashMap();

// hm.put("2018050401", new Student("2018050401", "张三", 18, 80.0));

// hm.put("2018050402", new Student("2018050402", "李四", 18, 80.0));

// hm.put("2018050403", new Student("2018050403", "李四", 18, 80.0));

// hm.put("2018050404", new Student("2018050404", "王五", 18, 80.0));

// hm.put("2018050404", new Student("2018050404", "王五", 18, 80.0));

//

// // 方式一: 通过键找值

// Set keys = hm.keySet();

// for (String key : keys) {

// Student s = hm.get(key);

// System.out.println(key + "|" + s.getId() + "|" + s.getName() + "|" + s.getAge() + "|" + s.getScore());

// }

HashMap hm = new HashMap();

hm.put(new Student("2018050401", "张三", 18, 80.0),"2018050401");

hm.put(new Student("2018050402", "李四", 18, 80.0),"2018050402");

hm.put(new Student("2018050403", "李四", 18, 80.0), "2018050403");

hm.put(new Student("2018050404", "王五", 18, 80.0), "2018050404");

hm.put(new Student("2018050404", "王五", 18, 80.0), "2018050404");

// 方式二: 通过键值对对象找键找值

Set> keyValues = hm.entrySet();

for (Entry keyValue : keyValues) {

Student s = keyValue.getKey();

String value = keyValue.getValue();

System.out.println(s.getId() + "|" + s.getName() + "|" + s.getAge() + "|" + s.getScore() + "=" + value);

}

LinkedHashMap

Map 接口的哈希表和链表实现,具有可预知的迭代顺序

特点:

键有序,唯一,

值有序,可重复,类似于List

底层数据结构是哈希表和链表,哈希表保证键唯一,链表保证键有序

LinkedHashMap lhm = new LinkedHashMap();

lhm.put(01, "张三1");

lhm.put(02, "张三2");

lhm.put(03, "张三3");

lhm.put(04, "张三4");

lhm.put(05, "张三5");

Set keys = lhm.keySet();

for (Integer key : keys) {

System.out.println(key + "|" + lhm.get(key));

}

TreeMap

基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,

具体取决于使用的构造方法。

特点:

键可排序,唯一,

值有序,可重复,类似于List

底层数据结构是自平衡的二叉树,可排序

排序方式类似于TreeSet,分为自然排序和比较器排序,具体取决于使用的构造方法

TreeMap tm = new TreeMap();

tm.put(24, "Hello1");

tm.put(14, "Hello2");

tm.put(34, "Hello3");

tm.put(124, "Hello4");

tm.put(24, "Hello5");

tm.put(24, "Hello6");

tm.put(24, "Hello7");

tm.put(244, "Hello8");

tm.put(624, "Hello9");

tm.put(24, "Hello10");

Set keys = tm.keySet();

for (Integer key : keys) {

String value = tm.get(key);

System.out.println(key + "|" + value);

}

HashTable

此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值

特点:

不允许null键和null值

线程安全,效率低

HashMap和Hashtable的区别:

HashMap是不安全的不同步的效率高的 允许null键和null值

Hashtable是安全的同步的效率低的 不允许null键和null值

底层都是哈希表结构

Hashtable hashtable = new Hashtable();

hashtable.put("刘备", "孙尚香");

hashtable.put("孙策", "大乔");

hashtable.put("周瑜", "小乔");

hashtable.put("吕布", "貂蝉");

System.out.println(hashtable);

Enumeration keys = hashtable.keys();

while (keys.hasMoreElements()) {

String key = keys.nextElement();

String value = hashtable.get(key);

System.out.println(key + "|" + value);

}

WeakHashMap

以弱键 实现的基于哈希表的 Map。在 WeakHashMap 中,当某个键不再正常使用时,将自动移除其条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。

丢弃某个键时,其条目从映射中有效地移除,因此,该类的行为与其他的 Map 实现有所不同。

WeakHashMap whm = new WeakHashMap<>();

whm.put(new String("hello1"), "world1");

whm.put(new String("hello2"), "world2");

whm.put(new String("hello3"), "world3");

whm.put("hello4", "world3");

System.out.println(whm);

System.gc();

System.runFinalization();

System.out.println(whm);

键是枚举类型

EnumMap em = new EnumMap<>(Direction.class);

em.put(Direction.UP, "向上移动");

em.put(Direction.DOWN, "向下移动");

em.put(Direction.LEFT, "向左移动");

em.put(Direction.RIGHT, "向右移动");

Set keys = em.keySet();

for (Direction key : keys) {

String value = em.get(key);

System.out.println(key + "|" + value);

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java Volatile关键字实现原理过程解析
下一篇:Java synchronize底层实现原理及优化
相关文章

 发表评论

暂时没有评论,来抢沙发吧~