Java集合
原生的数组删除元素不方便,长度是固定的,容量不够时,还需要自己进行扩容。现实中,程序在运行时,数据会时刻变化,为了满足程序运行时各种变化的数据存储需求,Java语言中封装类许多的子类,来帮助我们完成不同数据的存储,这些类就成为集合类
Collection集合——定义了存储一组对象的方法,其子接口List和Set分别定义了存储方式,Set中的数据对象没有顺序且不可以重复,List中的数据对象有书勋且可以重复
一、Collection
1.1 List
list集合存储元素的特点是有序(存储的先后顺序)且可以重复
1.1.1 ArrayList
底层实现时数组,优点使根据所以访问元素效率高,缺点是随机增删元素效率低,涉及到数组中其他元素的移动,并且还涉及到数组的扩容问题
1.1.2 LinkedList
底层实现是双向链表,优点是随机增删元素效率高,只需要改变新增节点的pre,next节点和pre节点的next和next节点的pre即可,缺点是随机访问效率低,只能从一端进行遍历,效率低于数组的随机访问
1.1.3 Vector
底层实现与ArrayList一致都是数组,但是Vector类中的方法都有synchronized
关键字,导致效率低,所以现在很少使用
1.1.4 遍历方式
第一种:for 循环。
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + ",");
}
第二种:迭代器。
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.print(it.next() + ",");
}
第三种:for-each。
for (String str : list) {
System.out.print(str + ",");
}
1.2 Set集合
Set集合存储元素的特点是无序(添加顺序)且不可以重复,不可以使用下标对元素操作
1.2.1 HashSet
HashSet集合其实是由HashMap实现的,只不过值由一个固定的Object填充,而键用于操作。
HashSet集合存储元素时,会先调用hashCode()方法计算hash值,为了快速判断添加元素是否重复。但是某些元素之间hash值会冲突。这个时候会再调用equals()方法比较元素是否一致。这种判断添加元素是否重复的方式既快速又安全。
1.2.2 TreeSet
和HashSet集合不同的是,TreeSet集合是一种基于红黑树实现的有序集合,它继承了SortedSet接口,可以自动对集合中的元素进行排序。按照比较器指定的方式进行排序。
我们自己定义的类也可以进行排序,只需要实现Comparable接口就可以排序了,否则会报错:类不能转化称为Comparable异常
和以前Arrays.sort()方法一致,目前来,只要是可以排序的类都必须要实现Comparable接口
二、Map
Map保存的是键值对,键要求唯一性,值可以重复。
2.1 HashMap
HashMap是Java中最常用的数据结构之一,用于存储键值对。在HashMap中每个键都能映射到一个唯一的值,可以通过键来获取对应的值。
1.hash方法原理:
先获取key对象的hashCode值,然后使用其高位与低位进行异或操作,得到一个新的hash值。这样计算hash值的方法可以避免hash冲突。
2.向HashMap添加元素
HashMap的内部实现是通过一个数组和链表或红黑树的组合来实现的,当我们不断向集合中添加元素时,
当计算出来hash值对应的位置上没有元素,会创建一个新节点,挂到该位置上。当这个位置有元素了,会挂到链表尾部。在这个过程中如果出来key相同的情况就会对该节点的值进行覆盖。在持续添加过程中如果使用hash数组的空间大于加载因子×数组大小的话会导致数组扩容到原来二倍,并且将元素重新散列。如果在向某个位置持续添加元素导致链表尺寸大于8并且hash数组长度大于64便会将该链表转化为红黑树。这种使用数组+链表/红黑树的结构既保证了查询效率又保证了增删效率,另外扩容机制也是使用空间换取时间的体现。
2.2 TreeMap
可以存储键值对,对键进行自动排序,键的类型必须实行按Comparable接口。
2.3 Hashtable
Hashtable底层结构和HashMap类似,但是Hashtable是线程安全的,不能存储为null的key