JavaEE学习之【List,Set集合底层的数据结构】

来源:互联网 发布:电视CTR数据 编辑:程序博客网 时间:2024/05/21 09:04

List集合存储数据的结构

List接口下有很多个集合,它们存储元素所采用的结构方式是不同的,这样就导致了这些集合有它们各自的特点,供给我们在不同的环境下进行使用。数据存储的常用结构有:堆栈、队列、数组、链表。我们分别来了解一下:

 堆栈,采用该结构的集合,对元素的存取有如下的特点:

先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。

 栈的入口、出口的都是栈的顶端位置

 压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。

弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置。

栈的结构示意图如下:

队列,采用该结构的集合,对元素的存取有如下的特点:

 先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,安检。排成一列,每个人依次检查,只有前面的人全部检查完毕后,才能排到当前的人进行检查。

n队列的入口、出口各占一侧。例如,下图中的左侧为入口,右侧为出口。(结构示意图如下:)


数组,采用该结构的集合,对元素的存取有如下的特点:

查找元素快:通过索引,可以快速访问指定位置的元素

增删元素慢:

 指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置。如下图

 指定索引位置删除元素:需要创建一个新数组,把原数组元素根据索引,复制到新数组对应索引的位置,原数组中指定索引位置元素不复制到新数组中。(结构图如下)


链表,采用该结构的集合,对元素的存取有如下的特点:

 多个节点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。

 查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素

 增删元素快:

 增加元素:操作如左图,只需要修改连接下个元素的地址即可。

 删除元素:操作如右图,只需要修改连接下个元素的地址即可。

结构示意图如下:


哈希表

1:Hash表是查询速度最快的存储方式

它的底层有3种存贮方式,一种是纯数组存贮,一种是数组挂链表存储,还有一种是链表挂链表。

哈希底层3种结构图如下:



当需要把某些对象给哈希表中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在哈希数组中的位置,然后把这个对象存放在哈希数组中。

当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCodeequals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCodeequals方法建立属于当前对象的比较方式。

//重写代码如下:

@Override

public int hashCode() {//我这里的重写目的是为了通过年龄和名字来计算哈希值,如果不重写,默认是通过对象的地址值来计算哈希值

final int prime = 31;

int result = 1;

result =prime *result + age;

result =prime *result + ((name ==null) ? 0 :name.hashCode());

return result;

}

@Override

public boolean equals(Objectobj) {

if (this ==obj)

return true;

if (obj ==null)

return false;

if (getClass() !=obj.getClass())

return false;

Student other = (Student) obj;

if (age !=other.age)

return false;

if (name ==null) {

if (other.name !=null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}



原创粉丝点击