集合是一个承载元素和数据的容器。
集合就是多种数据结构。java中有很多的集合每一个集和都有不同的数据结构
集合容器在不断向上抽取过程中,出现了集合体系。在使用一个体系的原则:参阅顶层内容。建立底层对象。
集合两大体系架构图
集合数组的区别!
数组是固定长度的;集合可变长度的。
数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。
数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。
还可用于保存具有映射关系的关联数组就是键映射到值上。
映射就是把两个对象对应起来。
对应的对象叫做象,被对应的对象叫做原象。
也就是确定了唯一性一个键只对应一个值
Collectio
单列数据
List
元素有序且可重复的
Arraylist
1线程不安全,2数组的实现,3因此查询速度极快,
//开发中建议使用带参构造器创建ArrayList(int capacity),避免频繁扩容。
Linkedlist
1线程不安全,2双链式链表。3因此插入和删除极快
总结
LinkedList的遍历和ArrayList完全一致
添加和删除比较频繁的话,就使用LinkedList
查看和修改比较多的话,就使用ArrayList
Set
元素无序且唯一的
1、无序性:不等于随机性,存储的数据在底层数组中并非按照数组索引的顺序添加,而是根 据哈希值决定的。
哈希值
哈希值就是每一个文件或每一个字段都有不同的哈希值哈希值同样也会随着你文件大小 的变化和字段的变化而变化
2、不可重复性:Set判断两个对象是否是唯一的时使用equals()方法和hashCode()方法来判断 两个值是否一样,不能返回true,即相同的元素只能添加一次添加元素的过程:以HashSet为例
HashSet
底层原理就是HashMap
TreeSet
底层原理是hashmap而hashmap的底层原理是红黑树
1输出结果有序,2查询速度快,比list还要快,3二叉树不允许重复的数据添加进去。
Map
双列数据 存储key-value对的数据,key不能重复,值可以覆盖。 并且有映射关系
Map的实现类有:
hashmap
由数组-链表-红黑树组成
Arraylist底层原理
JDK1.7中的ArrayList
ArrayList list = new ArrayList();//底层创建了一个长度为10的Object[]数组
当添加的元素个数不超过10时,底层的数组是不会扩容的,超过之后会将数组扩容成原
数组长度的1.5倍,同时将元素组中的元素拷贝到新数组中。
JDK1.8中的ArrayListArrayList list = new ArrayList();//底层创建了一个长度为0的Object[]数组当第一次添加元素时,在创建一个长度为10的数组(类似于饿汉式:延迟加载、节省内存),之后的扩 容和JDK1.7中的方式相同
总结:开发中建议使用带参构造器创建ArrayList(int capacity),避免频繁扩容。
1.7中创建集合的时候就创建一个长度为10的数组当我们数组超过了临界值(临界值就是负载因子(0.7---0.75之间)乘当前数组长度)数组就会自动扩容1.5倍
Linkedlist底层原理
LinkedList内部声明了数据类型为Node的属性first、last,用来记录首末元素,默认值是null,同时定义了内部类Node,作为LinkedList中保存数据的基本结构(双向链表),Node类中定义了两个属性:
pre:记录前一个元素的位置
next:记录后一个元素的位置
当通过add(“a”) 添加一个元素时,会将”a”传到Node内部类中,将其封装成一个Node对象
通过Node可以看出LinkedList是一个双向链表
HashSet底层原理
向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法
计算出在HashSet底层数组中的存放位置(就是索引位置),判断数组此位置是否已经有了元素,
如果没有元素,就将元素添加进去,
如果有了元素(或以链表形式存在的多个元素),则比较元素a和此位置上的其他元素的hash值
如果相同:那就再调用a的equals()方法,和其他的元素进行逐一比较如果返回true则,元素添加失败,返回false添加成功。
添加成功之前:如果此位置上已经有了元素,那么他们以链表的方式存储共同占有此位置,
JKD 7:元素a放在数组中,指向原来元素
JKD 8:原来的数据方法数组中,指向新添加的元素a(七上八下)
HashMap底层原理
JDK7:数组+链表
HashMap map = new HashMap()//底层创建了一个数组长度为16:Entry[] table
当向map中添加数据时:map.put( keyN , valueN );之前可能添加过很多元素了。
首先计算keyN所在类的hashCode()方法,返回哈希值,计算之后得到其在数组中的位置
如果此位置上的数据为空,那么 keyN-valueN添加成功。
当此位置不为空,那么此位置上存在一个或者多个数据(他们以链表的形式存储),那就需要去比较
keyN和此位置上其他存在的一个或者多个数据的哈希值,如果都不相同,那就添加成功。
keyN和此位置上其他存在的一个或者多个数据的哈希值,如果有相同的,那就需要
调用keyN的equals()方法和上面相同的进行比较,
如果相同:valueN覆盖掉它,如果不相同:那么添加成功
扩容方式为:当添加的元素个数超出临界值时(并且要存放的位置不能为空),就会扩容为原来数组长度的两倍,并将原数组中的数组拷贝到新数组中
JDK8:数组+链表+红黑树
HashMap map = new HashMap()//底层创建了一个长度为0的Node[]数组,不是Entry[]了在首次调用put(key1,value1)时,才会在底层创建一个长度为16的Node[]数组当数组上的某一索引位置上的元素(以链表形式存储)个数超过了8,并且 当前数组的长度超过了64时
此时:此索引位置上的所有元素改为用红黑树存储(查找效率高)。
迭代器(iteration)
迭代器会自带一个指针刚开始都是从第一个开始的所以一个迭代器只能使用一次
list特有的迭代器有其他方法还可以使用
用于遍历集合
其底层原理是判断有没有下一个元素不为空(null)则输出下一个元素直到循环内没有下一个元素
List特有的迭代器(ListIteration)
Collection里的方法
ArrayList里常用的方法
LinkedList里增加的方法
TreeSet里的方法
Map里的常用方法
Map底层原理的一些名词
Collections工具类是专为集合开发的一个工具类为集合提供一些方法使用所用集合都可以使用
Collections还提供了一些排序的方法
都是static方法课类名.方法名直接调用