Collection和Map以及相关数据结构
工欲善其事,必先利其器。本片内容讲述java中的Collection和Map所用到的数据结构以及相关结构。
数据结构
-
顺序存储结构(用一段地址连续的存储单元一次存储线性表的数据元素)
数组:相同数据类型的元素按一定顺序排列的集合。
特点:
1.数组的内存是连续的
,想要访问那个元素直接从数组的首地址向后偏移就可以访问到
2.数组插入和删除数据效率低,如果在头部删除,插入,时间复杂度是O(n):相应的数据需向前或向后整体搬移。
3.数组的空间大小是固定的.
,不能动态扩容。 -
链式存储结构(地址可以连续也可以不连续的存储单元存储数据元素)
链表
单链表
节点:当前节点数据和下一个节点的地址
插入(三种方式:头插入、尾插入、中间插入)
双向链表
每一个节点既指向前驱又指向后继。
循环链表
循环链表,你可以想象成y一个闭环的链表。也就是最后一个元素又指向了第一个元素。
优点:不需要初始化容量,可任意加减元素;添加和删除操作只需改变前后两个节点的指针域指向地址即刻,所以添加,删除很快;
缺点:含有大量的指针域,占用空间较大,查找元素需遍历链表,非常耗时。 -
哈希表(Hash table,也叫散列表)
定义:根据键(key)而直接访问在内存存储位置的数据结构,也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度,这个映射函数交做散列函数,存放记录的数组叫做散列表。
关键字:
key:输入待查证的值
value:获取的内容
hash值:key通过hash函数算出的值(对数组长度取模,便可得到数组下标)
hash函数(散列函数):存在一中函数F,根据这个函数和查找关键字key,可以直接确定查找值所在位置,而不需要一个个遍历比较。
直接定制法
数字分析法
平方取中法
折叠法
除留余数法
H(key)=key MOD p (p<=m m为表长,p为质数
设计考虑因素?
计算散列地址所需要的时间(即hash函数本身不要太复杂)、
关键字的长度
表长
关键字分布是否均匀,是否有规律可续
设计的哈希函数在满足以上条件的情况下尽量减少冲突
什么是hash冲突?
对不同关键字可能得到同一散列地址,即k1≠k2,而f(k1)=f(k2),或f(k1) MOD 容量 =f(k2) MOD 容量,这种现象称为碰撞,亦称冲突。
本片文章所介绍数据结构时比较典型了以及常用的,类似队列、二叉树、栈等数据结构自行百度。
关系图
Collection接口相关
*集合是什么?
1.集合只能存放对象(基本类型自动转为引用类型)。
2.集合存的是多个对象的引用,对象本身还是在堆内存中。
3.集合可以存放不同类型,不限定数量的数据类型。
*集合和数组的区别?
1.数组是静态的,数组一旦创建就无法改变其容量;集合是可以动态扩展容量。
2.数组存放的类型只能是一种(基本类型/引用类型),集合存放的类型可以不同的(不加泛型时添加的是Object类型,基本类型自动转为引用类型)
3.数组是java语言中内置的数据类型,是线性排列的,执行效率或类型检查,都是最快的。
4.数组创建时就声明了类型,而集合不用。
*Collection集合接口与Map接口有什么关系?
* 没有关系
*
*为什么要使用集合?
* 集合底层依赖于数据实现的,数组一旦初始化后,其长度不可改变,无法改变其容量。
* 集合是动态的,可以根据需要改变集合的大小,并且解决了数据存放单一类型的缺点。
- Collection接口继承关系
*package java.util;
*public interface Collection<E> extends Iterable<E> {}
- Collection API详解
@return返回集合中元素的数量,如果改数量大于Integer.MAX_VALUE则返回Integer.MAX_VALUE值
* int size();
*
* @return用于判断集合中是否存在的元素,不存在则返回true
*boolean isEmpty();
*
* @return用于判断集合中是否存在指定的元素,存在返回true
*boolean contains(Object o);
*
* @return返回在此集合中的元素的迭代器
*Iterator<E> iterator();
*
* @return将集合转变成数组(慎用)
*Object[] toArray();
*
* @return将指定的集合转变成对应的数组
*<T> T[] toArray(T[] a);
*
* @return向集合中添加元素
* boolean add(E e);
*
* @return删除集合中指定的元素
* boolean remove(object o)
*
* @return判断集合中是否包含集合C
*boolean containsAll(Collection<?> c)
*
* @return将集合C添加到集合中
* boolean addAll(Collection<? extends E> c);
*
* @return删除集合中符合条件的元素 jdk1.8
* boolean removeAll(Collection<?> c);
* default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
*
*@return保留集合中集合C中的元素
* boolean retainAll(Collection<?> c);
*
* @return清空集合中的所有元素
* void clear();
*
*@return 比较o与集合中的元素
* boolean equals(Object o);
*
*@return返回此集合的哈希码值
* int hashCode();
*
*@return a {@code Spliterator} over the elements in this collection jdk1.8
*
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
@return返回一个连续Stream与此集合作为其源。jdk1.8
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
*@reuturn返回一个可能的并行Stream与此集合作为其源。 这是允许的这个方法返回一个连续的数据流。jdk1.8
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
Map接口相关
* map介绍
* 映射(map)是一个存储键、键值对的对象,给定一个键,可以查询得到它的值,键和值都可以是对象
* 键必须是唯一的,值可以重复(Map接口映射唯一的键到值)
* 键(Key)是以后用于检索值的对象,给定一个键和一个值,可以存储这个值到一个Map对象中,以后可以
使用对应的键来检索它
- Map接口继承关系
package java.util;
public interface Map<K,V> {}
- Map API详解
* @return存储键值对的个数
* int size();
* @return判断容器是否为空
* boolean isEmpty();
* @return判断容器中是否包含对应的键
* boolean containsKey(Object key);
* @return判断容器中是否包含对应的值
* boolean containsValue(Object value);
* @return获取键对应的值
* V get(Object key);
* @return把键值对添加到容器中
* V put(K key, V value);
* @return删除Map容器中对应key的值
* V remove(Object key);
* @return
* void putAll(Map<? extends K, ? extends V> m);
* @return
* void clear();
* @return
* Set<K> keySet();
* @return获取Map中所有的值
* Collection<V> values();
* @return返回包含映射关系的set视图
* Set<Map.Entry<K, V>> entrySet();
*
* @return Map.Entry接口代表映射项(键值对)类型,是Map的嵌套类型
* interface Entry<K,V> {
* @return
* K getKey();
* @return
* V getValue();
* @return
* V setValue(V value);
* //此处省略equals和hashCode以及jdk1.8新增方法
* }
*
* @return
* boolean equals(Object o);
* @return
* int hashCode();
* //此处省略jdk1.8新增方法
*/