目录
1.集合的概念
1.1概述
概念:对象的容器,集合中提供了常用的方法,可以实现与数组类似的存储
与数组的区别:
数组长度固定,集合是动态存储的
数组可以存基本类型和引用类型,集合只能存引用类型
1.2Collection接口
Collection: 集合的根接口
包含了两个子接口: 1. List 2.Set
//Collection的常用方法:
public class Test1 {
public static void main(String[] args) {
Collection co = new ArrayList();
co.add(1); //添加元素 Integer-自动装箱
co.add(3); //集合只能存对象?
co.add(2.5); //Double
System.out.println(co.contains(1)); //true
System.out.println(co.remove(1)); //删除单个对象
System.out.println(co.size()); //求长度
Collection co2 = new ArrayList();
co2.add(5);
co2.add(7);
System.out.println(co.addAll(co2)); //添加一个集合
System.out.println(co);
/*
co.clear();
System.out.println(co.isEmpty()); //true
System.out.println(co); //[] 不是null
*/
Object[] as = co.toArray(); //转数组
System.out.println(Arrays.toString(as));
}
}
2.List接口
2.1List
List接口,是Collection的子接口
包含了两个重要的实现类: ArrayList,LinkedList其中还有一个不太常用实现类Vector
List的特点:存储的元素有序(有序!=排序),可重复
public class Test1 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(3);
list.add(2);
list.add(3);
list.add(2, 6);
System.out.println(list); //1,3,6,2,3
System.out.println(list.get(2)); //根据下标获取元素
//循环遍历
for(int i=0;i<list.size();i++) {
System.out.print(list.get(i)+"\t"); //获取循环遍历的元素
}
System.out.println();
//增强for
for(Object o :list) { //将集合的元素,挨个取出来
System.out.print(o+"\t");
}
System.out.println();
//迭代器:
Iterator it = list.iterator();
while(it.hasNext()) { //循环判断是否有下一个
System.out.println(it.next()); //取出来后,指向下一个
}
}
}
2.2Vector实现类
Vector与ArrayList的区别
Vector是加了锁,安全,性能低
ArrayList没有加锁,不安全,性能高(重点)Vector提供了一些自身独有的方法
public class VectorTest {
public static void main(String[] args) {
Vector vector = new Vector();
/*
vector.add(1);
vector.add(3);
vector.add(2);
vector.add(3);
System.out.println(vector);
*/
//vector独有的方法
vector.addElement(1);
vector.addElement(3);
vector.addElement(2);
System.out.println(vector);
//循环遍历与ArrayList类似,有基本for,有迭代器,还有自身独有的遍历
Enumeration enu = vector.elements(); //通过枚举器遍历
while(enu.hasMoreElements()) { //判断是否有元素
System.out.println(enu.nextElement()); //如果有则取出来,指向下一个
}
}
}
2.3ArrayList实现类
LinkedList的操作:
与ArrayList的操作完全一致,只是存储原理不同
ArrayList的存储原理:通过数组扩容的方式存储
分析方式:
1.画图分析原理 2.分析源码(找主线)LinkedList的存储原理:通过双向链表存储
分析方式:
1.画图分析原理 2.分析源码(找主线)
public class ArrayListTest {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(3);
list.add(1);
list.add(2);
System.out.println(list);
}
}
2.3.1ArrayList存储原理分析
2.3.2LinkedList存储原理分析
2.3.3ArrayList与LinkedList性能PK
分析增删改查:
1. 向后追加:相差不大,ArrayList稍快
2. 指定位置的删除和添加
ArrayList集体搬迁 PK LinkedList定位==》LinkedList稍快,
如果连续指定位置增删,LinkedList快很多
3. 修改和查找
ArrayList快结论:经常使用ArrayList,因为常用的操作是定位和向后追加
public class ArrayListTest2 {
public static void main(String[] args) {
List list = new LinkedList();
long start = System.currentTimeMillis();
for(int i=0;i<10000;i++) {
list.add(i);
}
System.out.println(System.currentTimeMillis()-start);
}
}
3.泛型
3.1泛型应用
//案例: 通过List存储自定义对象
class Person{
String name;
public Person(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
//问题1:警告太多,清理黄线 2.假设存其他引用类型,编译是通过的,运行时报错
//报错提示:类型转换异常
//解决方案:从源头上规避问题,存值前约束所存储的类型为Person类型--泛型
List<Person> list = new ArrayList<>();
list.add(new Person("貂蝉"));
list.add(new Person("小乔"));
list.add(new Person("大乔"));
//list.add("高圆圆"); //从源头上规避了其他类型的值的存储
//循环遍历,获取对象的属性
Iterator<Person> it = list.iterator();
while(it.hasNext()) {
//ClassCastException: String cannot be cast to Person
Person person = it.next(); //有了泛型约束,无需强转
System.out.println(person.name);
}
}
}
3.2泛型定义
概述: 参数化类型,把类型作为参数传递,约束了所存储值的类型
常见的泛型分类:
泛型类(常用) 泛型接口(常用) 泛型方法
语法: <T>
//泛型类: MyFan <T>: 约束泛型类中所有使用泛型参数的方法所传的类型
class MyFan <T>{
public void add(T t) {
System.out.println(t);
}
}
//泛型接口:FanInter<T>:约束泛型中接口传递类型,泛型接口实现类也需要定义泛型
interface FanInter<