Java集合框架
1.定义
在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类)。
所有抽象出来的数据结构和操作(算法)统称为Java集合框架。
2.集合框架的内容
所有集合类都位于java.util包下。
Java的集合类主要由两个接口派生而出:Collection和Map,
Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
2.1、 List接口
List接口的就是有序、不唯一的数据存储
常用方法
添加元素:
add(Object类型值)方法
获取元素
get(下标)方法
获取集合大小(存放元素个数)
size()方法, 如果size()返回值为0,代表集合为空
判断集合是否包含某个元素
contains(元素)方法
判断集合是否非空
isEmpty()方法
集合一步转换为数组对象
调用toArray()方法
数组一步转换为集合
使用Arrays.asList(数组);
2.2、List接口常用实现类
(1)ArrayList类
ArrayList实现了可变大小的数组
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断
添加新元素而自动增加。
底层实现是数组容量自动扩充的,如果是空参构造,长度为0,调用add之后,初始10个长度,后续到达
默认容量后,都自动扩容原有长度的一半,如果指定初始容量,不会自动扩容,实际上可变就是把之前
数组内容拷贝到新的扩容的数组中
ArrayList没有同步,即不安全。
ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高.
ArrayList允许存放null值元素
ArrayList <Integer> a = new ArrayList();//创建一个ArrayList集合
a.add(26787);//往集合中添加元素
a.add(245);//往集合中添加元素
a.add(23333);//往集合中添加元素
a.remove(1) ;//移除此列表中指定位置上的元素
System.out.println(a.get(1));//返回指定索引位置上的元素
a.set(1,6666);//用指定的元素替代此列表中指定位置上的元素
//遍历集合
for (Integer i:a) {
System.out.println(i);
}
//迭代器遍历集合
Iterator<Integer> iterator = a.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
(2)LinkedList类
LinkedList实现了List接口,允许null元素。
LinkedList采用链表存储方式。
由于它的底层是用双向链表实现的,所以没有初始化大小,也没有扩容的机制,
就是一直在前面或者后面新增就好。
插入、删除元素时效率比较高,遍历和随机访问效率比较低,需要二分进行查找。
小结:
(1)ArrayList底层实现是动态数组,所以遍历和随机访问元素的效率高,末尾插入数据实际
跟LinkedList差不多,但如果是中间插入数据,要移动元素,导致数组重新分配,所以效率差,
不适合快速插入和删除
(2)而对LinkedList而言,插入元素,不管什么位置,这个开销是统一的,分配一个内部Entry对象,
但是遍历或者随机访问元素,要移动指针查找,效率低。
(3)二者都是线程不安全的,存放元素都是有序,不唯一。
2.3、Set接口及其常用类
特点:无序的:不保证元素的插入次序。
唯一:Set中存放的是对象的引用,所以相同的对象是没法添加到集合中,即集合中不允许
有相同的元素对象。主要先根据hashcode值,如果相同再看是否重写了equals方法。
注意:虽然Set中元素没有顺序,但是元素在set中的位置是由该元素的HashCode决定的,其具体位置
其实是固定的。
常用实现类:
HashSet :
它不允许出现重复元素;不保证集合中元素的顺序
允许包含值为null的元素,但最多只能有一个null元素。
HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能。
TreeSet :
可以实现排序等功能的集合,它在讲对象元素添加到集合中时会自动按照某种比较规则将其插入
到有序的对象序列中,并保证该集合元素组成按照“升序”排列。TreeSet是一个有序集合,其底层是
基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排
序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不
带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带
比较器的参数。
2.5、Map接口
存放的内容为:key-value键值对。
Map中的每一个元素包含“一个key”和“key对应的value”。
Map主要用于存储健值对,根据键得到值,因此不允许键重复,但允许值重复。
HashMap是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的
访问速度。
HashMap最多只允许一条记录的键为null;允许多条记录的值为 null;
HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,否则可能会导致数据的不一致。
常用方法:
添加键值对的方法
使用put(key, value)方法
获取键值对
使用get(key)方法
获取结合键值对的个数
使用size()方法
判断map集合中是否包含某个键值对
使用containsKey(key)方法
判断map集合中是否包含某个值
使用containsValue(value)方法
删除键值对
使用remove(key)方法
获取集合中所有的键
使用keySet()方法
获取集合中所有的值
使用values()方法
HashMap中可以存放null值作为key,但只能有一个key为null
HashMap中可以存放多个null值作为value,没有限制
Map中存放键值对,如果发现key已经存在,会覆盖对应原有的值,key不变(因为是set集合)
HashMap集合重写了toString方法
2.6、泛型
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
Java中的泛型标记符
E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
? - 表示不确定的 java 类型