- Java集合概述
1)集合和数组都是对多个对象进行存储的作用(内存层面),它们都是一种容器。
2.1)数组在存储多个数据方面的特点:
》一旦初始化,长度就确定了
》数组一旦定义好,其元素类型也确定了,只能操作指定类型的数据。如 String[ ] arr, int [ ] arr1。
2.2)数组在存储多个数据方面的缺点:
》一旦初始化以后,其长度不可修改
》数组中提供的方法非常有限,对于添加、删除、插入数据等操作非常不便利。
》获取数组中实际元素的个数的需求,数组没有现成的属性、方法可用。
》数组存储数据的特点:有序、可重复,对于无序、不可重复需求,数组无法满足。
Java集合可分为Collection和Map两种体系
》Collection接口:单列数据,定义了存取一组对象的方法的集合
–List: 有序、可重复集合
–Set: 无序、不可重复集合
》Map接口:双列数据,保存具有映射关系的“Key-Value”对的集合。
- Collection接口方法
boolean add(E e)
boolean addAll(Collection<? extends E> c)
void clear()
int size()
boolean isEmpty()
boolean contains(Object o): 调用了equals()方法来比较
boolean containsAll(Collection<?> c):
boolean remove(Object o): 也是先调用equals()方法看是否包含
boolean removeAll(Collection<?> c)
boolean retainAll(Collection<?> c)
boolean equals(Object c)
Object [ ] toArray();
int hashCode()
Iterator iterator()
- Iterator迭代器接口
集合元素的遍历。Iterator对象称为迭代器(设计模式的一种),为容器而生。
hasNext():指针不下移。
next():指针下移,并返回下移后指向的对象。
remove(): 删除当前游标指向的元素,不能删除两次。
while(iterator.hasNext()){
System.out.println(iterator.next());
}
注意:a. 遍历时不能每次新造Iterator对象。 b. 每次调用next()方法,游标指针都会下移。
JDK5.0新增foreach循环也可遍历集合
for (Object obj : collection) {
System.out.println(obj);
}
逐个将集合中的元素赋值给obj变量,直到遍历完成。内部也是使用迭代器实现的。
- Collection子接口:List
三个实现类:ArrayList; LinkedList; Vector
不同点
ArrayList:作为List接口的主要实现类。线程不安全,效率高。底层使用Object [ ]。
LinkedList:对于频繁的插入和删除操作,使用此类效率更高。其底层使用双向链表存储。
Vector:古老实现类,基本已经很少用了。线程安全,效率低。
ArrayList源码分析。
JDK1.7:如果能预知大概长度,推荐使用带参构造器,防止扩容引起性能损失。
JDK1.8:调用add()方法时,才创建长度为10的数组,后续扩容与1.7无异。
E get(int index)
E set(int index, E element)
void add(int index, E element)
E remove(int index)
boolean remove(Object o)
int indexOf(Object o)
int lastIndexOf(Object o)
List subList(int fromIndex, int toIndex): 左闭右开区间。
- Collection子接口:Set
存储的数据无序、不可重复,有三个实现类:
HashSet:作为Set的主要实现类。线程不安全的,可以存储null值。底层是数组+链表的结构。
LinkedHashSet:是HashSet子类,增加了链表指针。遍历时可以按照元素添加的顺序进行。
TreeSet:使用二叉树(红黑树)存储。可以按照对象的指定属性排序。
Set接口没有定义新的方法,所有方法都来自Collection接口。
以HashSet为例,无序性不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是按照哈希值。
不可重复性:保证添加的元素按照equals()方法判断时,不能返回true,即相同的元素不能重复添加。
添加元素的过程,以HashSet为例
a. 计算元素的哈希值,该哈希值决定了它在数组中存放的位置。
b. 如果该位置已有元素,则比较哈希值是否相同,如不同,以链表方式将旧元素指向新元素
c. 如果哈希值也一样,则调用equals()方法判断是否为相同元素,如果不相同,则以链表方式将旧元素指向新元素
LinkedHashSet:在原有的HashSet基础上,每个数据还维护了两个变量,记录此数据的前一个和后一个数据。对于频繁的遍历操作,效率高于HashSet.
TreeSet:向TreeSet当中添加的数据,必须为同一个类的对象。两种排序方式自然排序和定制排序。在自然排序中,比较两个对象是否相同的标准为compareTo()方法返回0,不再是equals()。TreeSet不能放相同的数据,使用compareTo()比较的结果为准,只要返回0就认为是相同元素。
- Map接口
HashMap:作为主要实现类;线程不安全,效率高;可以存储null值的key或者value.
|----LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序进行遍历。
TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此处是使用key的值进行排序的(自然排序或定制排序)。TreeMap底层使用红黑树存储。
Hashtable:作为古老的实现类;线程安全,效率低
|----Properties:常用来处理配置文件
HashMap的底层:JDK7.0是数组+链表,JDK8.0是数组+链表+红黑树。
Map中的key:无序的、不可重复的,使用Set存储所有的key ----> key所在的类要重写equals()和hashCode()
Map中的value:无序的、可重复的,使用Collection存储所有的value
一个键值对:key-value构成了一个Entry对象
Map中的entry:无序的、不可重复的,使用Set存储所有的Entry.
HashMap底层实现原理
JDK7:
HashMap map = new HashMap()
实例化以后,在底层创建了长度16的一维数组Entry [ ]
…可能执行若干次put()…
map.put(key1, value1);
首先调用key1所在类的hashCode()方法计算key1哈希值,此哈希值经过某种计算方法后,得到在Entry数组中存放的位置。
如果此位置数据为空,此时的key1-value1添加成功。—情况1
如果此位置上的数据不为空,比较当前key1和已存在数据的key值的哈希值。
如果哈希值都不相同,此时key1-value1添加成功。—情况2
如果key1和某个数据的哈希值相同,继续比较equals()方法
如果equals()返回false,此时key1-value1添加成功。—情况3
如果euqals()返回true,使用value1替换相同key的value值。(相当于put()方法具有修改value值的功能)
补充:关于情况2和3,此时key1-value1和原来的数据以链表的方式存储。
在不断的添加过成功,会涉及扩容问题,默认的扩容方式是扩容为原容量的2倍,并将原有的数据复制过来。
JDK8相较于7在底层实现方面的不同:
- new HashMap()的时候底层尚未创建长度为16的数组。
- JDK8底层数组是Node[ ], 而非Entry[ ]
- 首次调用put()方法是,底层才创建长度为16的数组。
- JDK7底层只有数组+链表,JDK8中底层为数组+链表+红黑树,当数组的某一个索引位置上的元素以链表形式存在的数据>8且当前数组长度>64,此时此索引位置上的所有数据改为使用红黑树存储。
Map常用方法
增删改操作:
V put(K key, V value):将key-value添加(或修改)到当前map对象中
void putAll(Map<? extends K, ? extendsV> m):将m中所有k-v对存放到当前map中
boolean remove(Object key):移除指定key的key-value对,并返回value值。
void clear(): 清除当前map中的所有数据
查询操作:
V get(Object key):获取指定key对应的value
boolean containsKey(Object key): 是否包含指定key
boolean containsValue(Object value): 是否包含指定value
int size(): 返回map中k-v对的个数
boolean isEmpty(): 判断当前map是否为空
boolean equals(Object o):判断当前map和参数对象o是否相等
元视图操作方法:
Set keySet(): 返回所有key构成的Set集合
Collection values():返回所有value构成的Collection集合
Set entrySet(): 返回所有key-value对构成的Set集合。
Properties: 用于处理配置文件
- Collections工具类
Collections是操作Collection和Map的工具类。
排序操作(均为static):
reverse(List l): 反转list中的元素
shuffle(List l): 随机排列list中的元素
sort(List l): 自然排序
sort(List l, Comparator c):定制排序
swap(List l, int index, int index): 交换元素
Object max(Collection c)
Object max(Collection c, Comparator comp)
Object min(Collection c)
Object min(Collection c, Comparator comp)
int frequency(Collection c, Object o)
void copy(List dest, List src):注意dest.size()一开始是0,则复制的时候会抛出异常,应该按照src的size来指定dest的size。
boolean replaceAll(List list, Object oldVal, Object newVal):
Collections里面提供了多个synchronizedXxx()方法,将对应的集合转换为线程安全的。
List list1 = Collections.synchronizedList(list); //此时list1已经是线程安全的。
- 集合与数据结构相关