定义
用于存储多个数据
但是数组也可以
数组 与 集合 区别:
- 数组是定长的;集合的长度是任意的
- 数组存储同一种数据类型;集合可以存储不同的数据类型
- 数组可以存储基本和引用数据类型;集合只能存储引用数据类型
集合体系
泛型
< > :简化程序,减少类型转换
在目前集合体系中出现的可以理解为该集合的数据类型,E可以理解为某一种数据类型
Collection
- 单列集合层次的根接口,制定了集合的规范
- 定义了集合操作的方法,并没有提供直接实现,而是提供了直接子接口
- 一些集合存储的有序,一些无序 一些存储的数据可以重复,一些不可以 ;至于如何做到上述结果,要根据不同实现类来决定
演示:
因为Collection是接口,要演示其方法,就必须使用它的实现类,已ArrayList来演示。
public void test(){
/*
*虽然集合可以存储不同数据类型,但是大多数时候,
*集合存储同一种数据类型
*为了限制集合存储同一种数据类型,就使用泛型来约束
*/
// Collection coll = new ArrayList();
//使用泛型<String>,只能添加String类型,第四个、第三个会添加失败
// Collection<String> coll = new ArrayList<String>();
// 零型泛型
Collection<String> coll = new ArrayList<>();
// 添加元素
System.out.println(coll.add("a"));
System.out.println(coll.add("a"));
// System.out.println(coll.add(new Date());
// System.out.println(coll.add(1));//自动装箱 Integer i =1;
System.out.println(coll.add("c"));
System.out.println(coll);
//添加集合
Collection<String> coll2 = new ArrayList<>();
coll2.add("d");
coll2.add("e");
coll2.addAll(coll);
System.out.println(coll2);
//判断包含
Collection<String> coll3 = new ArrayList<>();
coll3.add("e");
coll3.add("f");
System.out.println(coll2.contains("a"));
System.out.println(coll2.containsAll(coll));
System.out.println(coll2.containsAll(coll3));
//移除匹配的单个
System.out.println("移除a是否成功" + coll2.remove("a"));
System.out.println(coll2);
//移除交集
coll2.removeAll(coll3);
System.out.println(coll2);
//移除除交集外的元素
coll2.retainAll(coll);
System.out.println(coll2);
//遍历集合:
// 方法1:转换成数组遍历集合
// 方法2:利用迭代器遍历集合
// 方法3:foreach ——增强for循环
// 转换成数组遍历集合
Object[] obj = coll2.toArray();//转换成Object[]类型
String[] str = coll2.toArray(new String[coll2.size()]);//转换成String[]
for(int i = 0; i < obj.length; i++){
System.out.println("obj:" + obj[i]);
System.out.println("str:" + str[i]);
}
//利用迭代器遍历集合
Iterator<String> i = coll2.iterator();
while(i.hasNext()){
String string = i.next();
System.out.println(string);
}
//foreach语法
// for(遍历将要得到的数据类型 变量名 : 要遍历的对象){}
for(String r:coll2){
System.out.println(r);
}
//清空
System.out.println("清空前元素个数:" + coll2.size());
coll2.clear();
System.out.println("清空后元素个数:" + coll2.size());
System.out.println("是否为空:" + coll2.isEmpty());
}
List
- List类型的集合存储的数据有顺序,有下标。
- List允许重复元素
- 与Collection父接口的区别是:多了一些操作集合的方法,多次的这些方法都与下标有关系。因为List的常用实现类ArrayList,LinkedList分别以数组和链表实现,他们都有下标。
ArrayList
- 实现自List,所以有序,允许重复,有下标
- ArrayList的底层是数组
- 默认容量是10
- 可以存储null元素
- ArrayList是不同步的 ——> 不保证线程安全
面试题:ArrayList的扩容机制
以无参数构造方法创建 ArrayList 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组容量扩为10。
https://juejin.im/post/5c66c47851882562e5443491
演示方法:
public void test(){
ArrayList<String> a1 = new ArrayList<>();
a1.add("a");
a1.add("b");
a1.add("c");
//在指定位置插入
a1.add(2,"c");
System.out.println(a1);
//根据下标获得值
System.out.println(a1.get(1));
//根据元素找到第一个匹配的下标
System.out.println(a1.indexOf("c"));
//根据下标替换
a1.set(3, "d");
System.out.println(a1);
//根据下标移除
a1.remove(3);
System.out.println(a1);
}
LinkedList
- 实现List接口,有序、允许重复
- 底层基于链表实现
- 可以存储null值
- 不同步,不保证线程安全
- 提供的方法与ArrayList的方法大部分相同
- 不同的在于,提供了一些专门操作开头和结尾元素的方法
原因:
ArrayList是基于数组的,内存空间中是连续的;
LinkedList是基于链表的,内存空间中不连续,虽然提供了查找下标的方法,但效率低下。
面试:
ArrayList根据下标查询更新效率高,但是插入删除效率低;
LinkedList根据下标查询更新效率低,但是插入删除效率高。