【数据结构】Map与Set结构详解
数据结构系列五:Map与Set(一)
一、接口的实现
1.方法上
2.成员上
二、Map的内外双接口结构
1.实现
1.1外部Map接口的实现
1.1.1临摹整体
1.1.2外部类实现整体
1.2内部Entry接口的实现
1.2.1临摹内部
1.2.2内部类实现内部
2.关系
3.意义
3.1逻辑内聚
3.2访问封装
3.3成套对应
三、Map实现类的存储结构
1.包装节点对象
2.数据组织结构
2.1数组+链表/红黑树
2.1.1结构
2.1.2顺序
2.1.3复杂度
2.2红黑树
2.2.1结构
2.2.2顺序
2.2.3复杂度
四、Map接口里的方法使用
1.外接口Map
1.1查询
1.1.1键查询值(无默认值):
1.1.2键查询值(有默认值):
1.2修改:
1.3删除:
1.4判断
1.4.1判断键存在:
1.4.2判断值存在:
1.5获取
1.5.1获取所有键:
1.5.2获取所有值:
1.5.3获取所有包装节点:
2.内接口Entry
2.1获取
2.1.1获取节点的键:
2.1.2获取节点的值:
2.2修改:
五、Set接口
1.复用性
2.定义分类
六、Set接口里的方法使用
1.获取
1.1获取所有元素:
1.2获取元素个数:
1.3获取迭代器:
2.添加
2.1添加一个元素:
2.2添加集合元素:
3.删除:
4.判断
4.1判断是否空:
4.2判断一个元素存在:
4.3判断集合元素存在:
5.清空:
一、接口的实现
接口是在实现类子类里完整实现的
1.方法上
接口处在被使用范围下时,在意义编译的要求下,一定要被连接有此接口的实现类 赋值向上转型 使得里面的抽象方法都被重写 有意义上:
因为这些抽象方法都无方法体的,每个抽象方法设置 有点意义的 也就只有形参类型、返回值类型,无完整意义的,所以抽象方法的完整实现是在实现类子类里完成的
2.成员上
接口里一般不会定义成员变量,更多时候成员变量都是在实现类子类这边 结合临摹要实现的抽象方法,在可创建的各样对象中根据具体需求 选择针对性地自定义实现的,从而达到接口实现的多样化,所以接口设置成在实现类里面创建成员变量是接口能多样化实现的保障
二、Map的内外双接口结构
public interface Map<K, V> {//外部Map整体接口//Map接口临摹 从外部、握整体操作包装节点:V put(K key, V value);V get(Object key);V remove(Object key);void putAll(Map<? extends K, ? extends V> m);void clear();...interface Entry<K, V> {//内部Entry局部接口//Entry接口临摹 每个包装节点对象自己对自身的操作:K getKey();V getValue();V setValue(V value);}
}
1.实现
1.1外部Map接口的实现
1.1.1临摹整体
外部Map整体接口的抽象方法 临摹着 从外部、握整体地能操作着 所有键值成对包装单位体
1.1.2外部类实现整体
对应到具体实现类那边,外部Map整体接口的实现类果真就额外有 操作所有包装单位整体的 入口成员变量,再配着 重写着的操作整体的实现方法,外部Map整体接口的实现类(即实现类整体中不包含内部Entry实现类的 外部Map实现类部分)实现了对包装单位从整体的操作
1.2内部Entry接口的实现
1.2.1临摹内部
内部Entry局部接口的抽象方法 临摹着 从内部包装单位体自身对自己范围内的内部操作
1.2.2内部类实现内部
对应到具体实现类那边,内部Entry局部接口实现类就额外有 包装单位自身的组成信息成员变量,配合着 重写着的包装单位自身内部操作实现方法,内部Entry局部接口实现类就也实现了 它每创的包装单位对象都能实现对自身信息的操作
2.关系
在每个Map实现类中,向整体Map接口向上转型间接实例的 从整体操作所有包装单位的 实例对象就只有它一个,而由它的内部类 向上转型Entry接口间接实例化的包装单位对象 创建得可就多了,即外部实现类Map一个实例对象管理着 内部类Entry的许多实例对象
3.意义
3.1逻辑内聚
接口里面装内部接口,内部接口Entry能访问外部接口Map 就直接固定设置成相同的泛型参数K、V 直接保证上 从整体视角与个体视角管理包装单位都要的 类型恒统一
3.2访问封装
内部接口加层封装于 外部使用者接口里面,使内部接口受正确限访问,包装得更加针对且安全
3.3成套对应
外部接口实例化时,由于抽象相关的 在去使用了的范围内 必须要重写实现上其意义,因此外部接口的实现类 也同时要求着 去重写实现有 内部接口相关的所有抽象的东西,即也要求同时有去实例化内部接口 也实现它的意义,所以这也就使得有内部接口的接口实例化 需要对应 有内部类的实现类来实现,接口与类对应着实现的(接口的实例化都是间接的)
三、Map实现类的存储结构
在Map对应实现类的引用管理对象体系中,最上层Map实现类的实例对象 通过分层向下管理 来组织基本节点对象的数据组织结构 或者由基本对象节点自连串自己 组织成数据组织结构,实现着最上层类引用对象 管理着 成组织数据结构中的每个单位基本节点对象
1.包装节点对象
Map数据结构里面的基本操作单位是 关键字对象与值对象对应两合并成的一个 键值对包装对象(String与Integer两合并包装成一个对象),而其它数据结构的基本操作单位都是一个底层直接对象(以Integer一个对象为基本操作单位)
2.数据组织结构
2.1数组+链表/红黑树
2.1.1结构
HashMap用数组+链表/红黑树的数据组织结构 组织包装节点对象:
- 将包装节点的键值 通过哈希函数计算映射到数组索引 来确定存放,每个数组元素哈希桶里面都是存放包装节点自实现作的一个链表头节点或者根节点
包装节点映射到数组同一位置时,节点会自连接组织 连接进桶里存放,到链表过长时 此数组元素哈希桶里面的链表节点 都会通过Node类extend继承扩展转为TreeNode类 全部转为红黑树节点 转化成装红黑树的哈希桶结构(提高查询效率)来继续存放在 此数组索引位置
2.1.2顺序
通过哈希函数计算映射索引 来确定元素在数组位置的,元素们用此函数来确定的位置之间 是无序的
2.1.3复杂度
一次哈希函数计算映射 就能锁定元素位置,数据操作查插删的时间复杂度都是O(1),哈希结构的存储能实现数据的极速操作
2.2红黑树
2.2.1结构
TreeMap中,通过在包装单位里面 定义自己自连串组织结构,包装单位们能 自组织成红黑树的结构(一种自平衡的二叉搜索树)
2.2.2顺序
包装单位按照键值的顺序 有序地在树中存储
2.2.3复杂度
通过比较搜索来确定元素的,数据操作查插删的时间复杂度都是O(logN),即树的高度次
四、Map接口里的方法使用
Map接口里只有抽象方法的临摹,抽象方法的实现、成员变量的定义存在、数据结构的组织都是在实现类TreeMap、HashMap中才有去实现的
1.外接口Map
外部接口对应实现的外部类 完成从外部整体 对自己里面创建的所有包装节点的 整体操作:
1.1查询
1.1.1键查询值(无默认值):
t/hMap.get(Object key);
—> return V
键查询获取 此map实现类创建的 包装节点数据组织结构里 某键值对象对应的 包装节点里的值
1.1.2键查询值(有默认值):
t/hMap.get(Object key,V defaultValue);
—> return V
键查询获取 此map实现类里面的 此键对应的包装节点的值,如果此创建的数据节点结构中 没有此键值的包装节点,则返回默认值
1.2修改:
t/hMap.put(K key,V value);
—> return V
修改设置 实现类map里面创建存储的 某键对应的 包装节点里的值
1.3删除:
t/hMap.remove(Object key)
—> return V
键查询删除 map里面对应的包装节点,并将此包装节点里的值对象返回
1.4判断
1.4.1判断键存在:
t/hMap.containsKey(Object key);
—> return boolean
判断map实现类里面创建的 所有包装节点中是否含有此键对象
1.4.2判断值存在:
t/hMap.containsValue(Object value);
—> return boolean
判断map实现类里面创建的 所有包装节点中是否含有此值对象
1.5获取
1.5.1获取所有键:
t/hMap.keySet();
—> return Set<K>
将map实现类里面创建的 所有包装节点的键对象 存放在Set集合中返回获取
1.5.2获取所有值:
t/hMap.values();
—> return Collection<V>
将map实现类里面创建的 所有包装节点的值对象 存放在Collection集合中返回获取(Set集合里面不会存放重复的值,value的值是可有重复的,就不要用Set集合接收 来用Collection集合接收了)
1.5.3获取所有包装节点:
t/hMap.entrySet();
—> return Set<Map.Entry<K,V>>
将map实现类里面创建的 所有包装节点向上转型回 接口类型的包装节点,存放在Set集合中返回获取
2.内接口Entry
内部接口对应实现的内部类 完成从内部每个包装节点对自身的操作,HashMap实现类里面用Node内部类 对应实现Entry内部接口,TreeMap实现类里面 用Entry内部类 来对应实现Entry内部接口:
2.1获取
2.1.1获取节点的键:
t/hEntry.getKey();
—> return K
获取该包装节点里面装的键对象
2.1.2获取节点的值:
t/hEntry.getValue();
—> return V
获取该包装节点里面装的值对象
2.2修改:
t/hEntry.setValue(V value);
—> return V
将该包装节点里面的值对象 修改设置为指定值对象
五、Set接口
1.复用性
Set与Map结构都是一样的,只是Set使用时 它的基本节点 键值包装对象 里面的值对象 统一设置成了Object类对象 来填充,相当于 不管查询意义的Object 连着存储,实现的也就是只针对键对象的 不重复数据的存储,它里面的元素 实际上就是包装节点下的键值
2.定义分类
Set实现类的底层 也都是复用Map实现类的那套,定义的基本操作对象 也都还是包装节点,但已忽略掉了值对象,相当于只存一个不会重复的 键对象节点了,所以在集合中把它单独定义分类出来 视为元素了,所以在集合中它的接口Set、它的实现类TreeSet、TreeMap都是定义在Collection接口下的
六、Set接口里的方法使用
Set接口里也是只有抽象方法的临摹,方法的具体实现、方法的操作对象也都在实现类TreeSet、TreeMap中 定义进行的
1.获取
1.1获取所有元素:
t/hSet.toArray();
—> return Object[]
将此set集合中的所有元素 装到数组中返回
1.2获取元素个数:
t/hSet.size();
—> return int
获取此set集合中的元素个数
1.3获取迭代器:
t/hSet.iterator();
—> return Iterator<E>
获取对应迭代此set集合元素的迭代器
2.添加
2.1添加一个元素:
t/hSet.add(E e);
—> return boolean
往此set实现类里面 添加存储一个元素,如果在实现类里面 元素已存储有,则不会添加成功
2.2添加集合元素:
t/hSet.addAll(Colleaction<? extends E> c);
—> return boolean
将集合c中的元素 全部添加到此set集合中,可以达到去重效果
3.删除:
t/hSet.remove(Object o);
—> return boolean
删除set实现的集合中的o对象元素
4.判断
4.1判断是否空:
t/hSet.isEmpty();
—> return boolean
判断此set集合是否为空
4.2判断一个元素存在:
t/hSet.contains(Object o);
—> return boolean
判断此set集合中是否有o对象元素
4.3判断集合元素存在:
t/hSet.containsAll(Collection<?> c);
—> return boolean
判断此set集合中 是否全部包含 集合c里面的所有元素
5.清空:
t/hSet.clear();
—> return void
清空此set集合