数组长度固定,集合长度不固定(数组实现,内部也不固定)
集合只能存储引用类型,数组基本类型和引用类型都可以
Collection
接口
无下标,无序
remove方法一次只能删除一个
使用增强for遍历时,实际使用的是迭代器
迭代器Iterator
专门用来遍历几个元素的一种方法(接口)
hasNext():有没有下一个元素,有返回ture
next():取下个元素
remove ()删除元素
Iterator iterator = collection.iterator();while (iterator.hasNext()){System.out.println(iterator.next());//只能用一次iterator.remove();
// collection.remove("chi");}
使用迭代器删除时,不允许使用集合删除增加,会出现 并发修改异常ConcurrentModificationException
判断
collection.contains("yan");//包含元素
collection.isEmpty() //是否为空
remove(),contain(),等方法都是调用equals()方法判断值是否相同的,而equals( ) 判断为this=obj;故当传入内容相同的引用类型时,会判断为false,需重写对象所属equals方法,保证正确判断相等
List
接口
有序,有下标,元素可重复(下标用于get,set,不能直接用)
添加基本类型整数型,会自动装箱,添加对应包装类,remove时参数要为引用类型如(object)5;如用整数,会被当成下标;直接删除浮点数元素,不会有问题(不会被判断成下标)
List list=new ArrayList();list.add(10);list.add(5);list.add(4);list.add(6);list.add(3.5)
// list.remove(10);报错,下标超界了list.remove((Object) 5);list.remove(3.5)//删除成功 System.out.println(list.toString());
列表迭代器
//列表迭代器 从前往后ListIterator listIterator = list.listIterator();while (listIterator.hasNext()){System.out.println();System.out.println(listIterator.next()+"-----"+listIterator.nextIndex());//从后向前ListIterator listIterator1 = list.listIterator(list.size());//不是列表长度减一,就是长度while (listIterator1.hasPrevious()) { System.out.println(listIterator1.previous());System.out.println(listIterator1.previousIndex());}}
结果
yan-----1
chi-----2
wang1-----3
会发现元素与其下标不对应
next方法会得到值并把光标后移,而nextIndex()不会移动光标。
ArrayList
必须开辟连续空间 运行速率快,线程不安全,查询快,增删慢
源码分析:
1.调用无参构造方法创建ArrayLIst集合,长度为size=0(size为实际元素个数),elementData 储存元素的数组
2.当添加第一个元素时,容量扩充为10,(DEFAULT_CAPACITY = 10;默认容量)之后每次扩容,容量都是原来的1.5倍
3.remove方法删除元素后移动数组使用System.arraycopy实现,效率快
4.迭代器中有一个cursor,获取一个元素后,cursor+1,如果cursor=size,就不能在向后进行了
LinkedList
无需开辟连续空间有序有下标,可重复
链表结构实现(双向链表),增删快,查询慢
源码分析:
1.构造方法没有任何操作,属性size=0 元素个数,head 头结点 last 最后一个节点
2. 静态内部类 Node 属性item;数据 next下一个元素 prev:上一个元素
3. add方法中每次添加都会形成一个节点,first属性指向第一个元素,last指向最后一个元素,其中每个元素都有前驱与后继。first没前驱,last没后继
两者比较
1ArrayList的存储结构是数组,LinkedList的存储结构是双向链表;
2.Array的查找遍历比较快,插入和删除相对较慢。因为使用本地方法优化,并不一定比LinkedList慢
3.LinkedLIst的插入和删除比较快,查找速度较慢
数组集合转换
数组转集合,转成的集合不能改变长度(不能增删)但能修改,会出UnsupportedOperationException 不支持操作异常
String[] s={"yan","chi","he"};List<String> list =new ArrayList<String>();list= Arrays.asList(s);//只能转成List型,再由此类型向其他类型转换//基本数组类型转换Integer[] nums={10,5,6,7,9,8};List<Integer> n=Arrays.asList(nums);
基本类型数组转集合,必须使用包装类
集合转数组
ArrayList<String> arrayList=new ArrayList<>();arrayList.add("yan");arrayList.add("chi");arrayList.add("he");String[] arr=arrayList.toArray(new String[0]);
new String[0]是为了使用泛型,也可写newString[数组长],但若给长了,多余元素为空,
Vector:
数组结构实现,查询快、增删慢;
JDK1.0版本,运行效率慢、线程安全
栈 队列
栈
stack:继承Vector
push入栈,pop出栈
LinkedList stack = new LinkedList();stack.push("yan");stack.push("chi");stack.push("he");System.out.println(stack.toString());int size = stack.size();for (int i = 0; i < size; i++) {System.out.println(stack.pop());}
队列
Queue:继承Collection
offer入队,poll出队
Queue query=new LinkedList();query.offer("yan");query.offer("chi");query.offer("he");int size = query.size();for (int i = 0; i < size; i++) {System.out.println(query.poll());}
Queue使用linkedlist实现
栈和队列都是每次进入长度加一每次出来长度减一,长度是在变得,所以遍历时需要先用遍历保存长度
泛型
参数化类型
常见形式有 泛型类,泛型接口,泛型方法
T:是一个占位符,表示一种引用数据类型,可以写多个
好处
提高代码的重用性
防止类型转换异常,提高代码的安全性
泛型类<>砖石语法
注意,1.不能使用T来实例化对象 2.不能包含使用泛型作为重载方法的参数
//JDK1.7之后实例泛型类型省略对象
class Student<T>{}
Student<String> student=new Student<>();
泛型接口
不能使用泛型T声明常量 只能声明方法
其实现类可以是泛型,也可以不是泛型
实现类是泛型
public class T1<T> implements Tinterface<T> {@Overridepublic T show() {return null;}
}
实现类不是泛型
public class T2 implements Tinterface<String> {@Overridepublic String show() {return null;}
}
泛型方法
在方法返回值前加泛型
public <T> T chi(T t){System.out.println("泛型方法");return t;}
泛型的上限和下限
泛型类不能做参数
public static void show(Tclass<T> tclass){//T位置报错System.out.println(tclass);}
}
编译后泛型T 变成Object
?表示任何类型
public static void show(Tclass<?> tclass){System.out.println(tclass);}
上限< ?extend T>;泛型只能是T的本身或子类
public static void show(Tclass<? extends Tclass> tclass){System.out.println(tclass);}
下限 <? super T>;泛型只能是T的本身或父类
public static void show(Tclass<? super Tclass> tclass){System.out.println(tclass);}
T应换成具体的引用类型
集合泛型
参数化类型、类型安全的集合,强制集合元素的类型必须一致
编译时即可检查,而非运行时抛出异常。
访问时,不必类型转换(拆箱)。
不同泛型之间引用不能相互赋值,泛型不存在多态
add只能添加student
增强for时直接写student类型,避免了强制类型转换
迭代器next()返回strudent类型
Collections工具类
所有方法都是静态方法
Collections.frequency(list, 10)查找元素出现个数
Collections.copy(dest,src) 要保证dest目标数组有大于源数组src的空间,否则报错
Collections.binarySearch(arrayList, 26)二分查找
max(),min()最大最小值