1. 集合概述
集合、数组都是对数据进行存储的结构,简称Java容器。
数组在初始化后长度确定,元素的类型确定,提供的方法有限,所以需要集合解决这些问题。
Java中的集合分为Collection和Map。通用的工具类Collections具有以下方法:
- Collections.reverse(反转)、shuffle(随机排序)
- sort(List,Comparator)、max(Collection,Comparator)
- min(Collection,Comparator):比较器可选
- swap(List,i,j):交换i j位置元素
- frequency(Collection,Obj):返回集合中obj出现的次数
- copy(List,List):后者复制到前者
- replaceAll(List,Obj,Obj):在List中用后一个对象替换前一个
2. Collection接口
Collection接口:单列集合,存储一个一个的对象。
- List接口:有序可重复,动态数组
- ArrayList、LinkedList、Vector
- Set接口:无序不可重复,集合
- HashSet、LinkedHashSet、TreeSet
其中主要使用的是ArrayList、LinkedList
2.1 List接口
存储有序可重复数据。
ArrayList:List的主要实现类,线程不安全,效率高,底层使用Object[] 存储
- 默认为空,add时才创建长度10的数组
- 容量不够时扩容为当前的1.5倍,最大为Int.MAX-8
- 所以尽量用带参构造器设定合适的大小
LinkedList:适合频繁插入和删除,底层使用双向链表存储,prev & next
Vector:List的古老实现类,线程安全,效率低,底层使用Object[] 存储,很少使用
2.2 List常用方法
- add()/addAll(int, coll):在int位置插入coll元素或coll中所有元素,后面元素后移
- get(int)
- indexOf(obj)/lastIndexOf(obj):首次/末次出现,没有返回-1
- remove(int):移除并返回,删除指定整数时需要装箱new Integer(int),否则按索引删
- set(int, obj):设置int位置变为obj
- subList(int, int):返回左闭右开子集
2.3 Set接口
存储无序不可重复数据。
- 无序性:不按索引存放,而是根据哈希值存放
- 不可重复性:用equals()判断
因此向Set中添加数据,其所在的类一定要重写HashCode和equals方法,并保证数据一致性
HashSet:主要实现类,线程不安全,可以存储null,底层是数组,通过HashMap实现
存放过程:
- 计算哈希值 – 计算数组中位置
- 该位置没有元素则添加,已有元素则比较哈希值
- 一致时再调用equals,还一致则重复,丢弃;不一致则添加到该位置的链表尾
LinkedHashSet:HashSet的子类,遍历时按照添加的顺序
- 添加到HashSet中时还维护了一个双向链表记录添加顺序
TreeSet:红黑树存储,可以按指定属性排序,所以只能放同一类数据
- 指定排序属性后,将该属性相同对象视为重复,需要继续改写compareTo
- 比较的两种方法:
- 自然排序: 创建对象时指定比较器,创建比较器进行比较
- 定制排序: 类实现Comparable接口,指定比较的属性
3. Map接口
Map与Collection并列存在,用于保存具有映射关系的数据,以键值对的形式存储,Map 中的 key 和 value 都可以是任何引用类型的数据。
与Set相同,Map的键也是无序不可重复,所以存放对象时需要重写HashCode和equals方法
3.1HashMap
主要实现类,线程不安全,效率高,可以存储null,基于数组+链表+红黑树(jdk8)
HashMap底层细节:
- 当实例化一个HashMap时,会初始化initialCapacity和loadFactor,在put第一对映射关系时,系统会创建一个长度为initialCapacity(=16)的Node数组
- 在这个数组中可以存放元素的位置我们称之为“桶”(bucket),每个bucket都有自己的索引,系统可以根据索引快速的查找bucket中的元素
- 每个bucket中存储一个元素,即一个Node对象,但每一个Node对象可以带一个引用变量next,用于指向下一个元素
- 当数组的索引上元素的链表长度>8且数组长度>64,则链表改为红黑树,不满足条件则扩容一倍解决
重要常量:
- DEFAULT_INITIAL_CAPACITY: 默认容量,16
- DEFAULT_LOAD_FACTOR: 默认加载因子,0.75
- threshold:扩容的临界值,=容量*加载因子
- TREE_THRESHOLD:Bucket中链表长度大于此值则转化为红黑树,默认8
- MIN_TREEIFY_CAPACITY:桶中Node被树化时最小的哈希表容量,默认64
3.2 其它实现类
LinkedHashMap:按照添加的顺序遍历,在原有的HashMap底层结构基础上添加了一对指针,指向前后元素
TreeMap:按照键值对进行排序,按照key进行自然排序或定制排序,底层使用红黑树
Properties:常用来处理配置文件,键值对都是String类型
Hashtable:古老实现类,线程安全,效率低
3.3 常用方法
- put/putAll/remove/clear/get/containsKey/containsValue/size/isEmpty/equals
- keySet():返回所有key组成的Set集合
- values():返回所有value组成的Collection集合
- entrySet():返回所有entry组成的Set集合
4. 泛型
- 泛型方法:public List copyList(E[] arrs){}
- G<? extends A>,只允许用A或A的子类, ?可以换成具体变量
- G<? super A>,只允许 A或A的的父类, ?可以换成具体变量