数据结构 - Map接口
Posted yuanjiangnan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 - Map接口相关的知识,希望对你有一定的参考价值。
简介
我们平时最常用的数据结构之一,内部是有键值对构成,Map集合中不能包含重复的键,但是可以包含重复的值。
Map接口
public interface Map<K,V>
Map 未实现方法
// 获取元素个数
int size();
// 是否为空
boolean isEmpty();
// 是否包含key
boolean containsKey(Object key);
// 是否包含value
boolean containsValue(Object value);
// 根据key取值
V get(Object key);
// 添加元素
V put(K key, V value);
// 移除key
V remove(Object key);
// 添加一个Map集合
void putAll(Map<? extends K, ? extends V> m);
// 清除
void clear();
// 获取整个key集合
Set<K> keySet();
// 获取所有值
Collection<V> values();
// 获取所有键值对
Set<Map.Entry<K, V>> entrySet();
// 比较是否一样
boolean equals(Object o);
// 获取集合hashCode
int hashCode();
Map 默认方法
default V getOrDefault(Object key, V defaultValue) {
V v;
// key不存在或key对应值为空返回默认值,否有返回实际值
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
根据key获取值,为空或不存在返回默认值
default V putIfAbsent(K key, V value) {
V v = get(key);
// key为空则添加
if (v == null) {
v = put(key, value);
}
return v;
}
如果key不存在或为空就添加此键值对
default boolean remove(Object key, Object value) {
Object curValue = get(key);
// value不一样或key不存在返回false
if (!Objects.equals(curValue, value) ||
(curValue == null && !containsKey(key))) {
return false;
}
remove(key);
return true;
}
如果key对应的值与value一样就删除
default boolean replace(K key, V oldValue, V newValue) {
Object curValue = get(key);
// 旧值与key对应值不同时返回false
if (!Objects.equals(curValue, oldValue) ||
(curValue == null && !containsKey(key))) {
return false;
}
put(key, newValue);
return true;
}
使用新值替换旧值,旧值与key对应值不同时返回false
default V replace(K key, V value) {
V curValue;
if (((curValue = get(key)) != null) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}
当key存在时,用value覆盖原值,不存在时返回空
Map 内部类Entry接口
interface Entry<K,V>
Map 内部类Entry方法
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
定义了基本键值对行为
AbstractMap抽象类
public abstract class AbstractMap<K,V> implements Map<K,V>
定了所有Map集合的基本骨架
AbstractMap属性
// 键集合
transient Set<K> keySet;
// 值集合
transient Collection<V> values;
AbstractMap构造函数
protected AbstractMap() {
}
AbstractMap未实现的方法
public abstract Set<Entry<K,V>> entrySet();
AbstractMap实现了Map接口中除entrySet()以外的方法。
AbstractMap已实现的方法
在这些已实现的方法中,只需要关注equals和hashcode方法即可,其他方法子类均已覆盖
public boolean equals(Object o) {
// 地址一样时为true
if (o == this)
return true;
// 不是Map或子类实例时为false
if (!(o instanceof Map))
return false;
// 强转o为Map
Map<?,?> m = (Map<?,?>) o;
// m长度为空
if (m.size() != size())
return false;
try {
// 遍历当前集合所有元素
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext()) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
// 有任意一个值不像等就返回false
if (value == null) {
if (!(m.get(key)==null && m.containsKey(key)))
return false;
} else {
if (!value.equals(m.get(key)))
return false;
}
}
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
// 循环完返回true
return true;
}
equals判断方式,先判断类型,在判断长度,之后判断元素,这跟List不同是,List中元素顺序不同会导致equals不同,这儿用的是包含和取值方式比较。第一个元素要么都是空,其他元素可以无顺序限制。
public int hashCode() {
int h = 0;
// 遍历所有元素
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
// 元素hashCode累加
h += i.next().hashCode();
return h;
}
hashcode方法是所有元素hashcode求和
以上是关于数据结构 - Map接口的主要内容,如果未能解决你的问题,请参考以下文章
Express实战 - 应用案例- realworld-API - 路由设计 - mongoose - 数据验证 - 密码加密 - 登录接口 - 身份认证 - token - 增删改查API(代码片段