Collection集合
一、概述
1.集合是Java中提供的一种容器可以用来存储多个数据
2.集合和数组的区别:
数组的长度是固定的,集合的长度是可变的
数组中存储的是同一类型的元素,可以存储基本数据类型值,集合存储的都是对象,而且对象的类型可以不一致,在开发中一般当对象多的时候,使用集合进行存储
二、集合框架
Collection接口的子接口包括List接口和Set接口,List接口又有Vector集合,ArrayList集合,LinkedList集合;Set接口又有TreeSet集合,HashSet集合,HashSet集合又有LinkedHashSet集合
1.学习集合的目标:
(1)使用集合存储数据
(2)会遍历集合,把数据取出来
(3)掌握每种集合的特性
2.List接口
(1)有序的集合(存储和取出元素顺序相同)
(2)允许存储重复的元素
(3)有索引,可以使用普通的for循环遍历
3.set接口
(1)不允许存储重复元素
(2)没有索引(不能使用普通的for循环遍历)
4.Collection接口:定义的是所有单列集合中的共性方法,所有的单列集合都可以使用共性的方法,没有带索引的方法
5.集合框架的学习方式:
(1)学习顶层:学习顶层接口/抽象类*性的方法,所有的子类都可以使用
(2)使用底层:底层不是接口就是抽象类,无法创建对象使用,需要使用底层的子类创建对象使用
6.Set接口的特点
(1)TreeSet集合与HashSet集合无序(存储和去除元素的顺序有可能不一致)
(2)LinkedHashSet集合是一个有序的集合
三、Collection里面的共性方法
1.public boolean add(E,e):把给定的对象添加到当前集合中 //一般都返回true可以不用接收
2.public void clear():清空集合中所有的元素
3.public boolean remove(E,e):把给定的对象在当前集合中删除 //集合中如果存在元素,删除元素,返回true,集合中如果不存在元素,删除失败返回false
4.public boolean contains(E、e):判断当前集合中是否包含给定的对象
5.public boolean isEmpty():判断当前集合是否为空
6.public int size():返回集合中元素的个数
7.public Object[ ] toArray():把集合中的元素存储到数组中
四、Iterator迭代器
1.Iterator接口
(1)迭代器是通用的取出集合中元素的方法
(2)迭代器工作方式:在取元素之前,先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出来,一直把集合中的所有元素全部取出
(3)常用方法:boolean hasNext( )如果仍然有元素则返回true next()返回迭代器的下一个元素
(4)注意:Iterator迭代器是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊
Collection接口中有一个方法,叫iterator(),这个方法返回的就是迭代器的实现类对象
Iterator<E> iterator( )返回在此collection的元素上进行迭代的迭代器
(5)迭代器的使用步骤:
使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
使用Iterator接口中的方法hasNext判断还有没有下一个元素
使用Iterator接口中的方法next取出集合中的下一个元素
2.增强for循环
(1)增强for循环是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的,她的内部原理其实是个Iterator迭代器,所以在遍历中不能对集合中的元素进行增删操作
(2)增强for循环:底层使用的也是迭代器,使用for循环的格式,简化了迭代器的书写,是JDK1.5以后出现的新特征
Collection<E>extends Iterable<E>:所有的单列集合都可以使用增强for(也就是foreach)
public interface Iterable<T>实现这个接口允许对象成为“foreach”语句的目标
增强for循环:用来遍历集合和数组
格式:
for(集合/数组的数据类型 变量名:集合名/数组名){
sout(变量名);
}
(3)新for循环必须有被遍历的目标,目标只能是Collection或者是数组,新式for仅仅作为遍历操作出现
五、泛型
1.泛型是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型
2.泛型也可以看作一个变量用来接收数据类型
E e:element元素
T t:Type类型
3.创建集合对象的时候就会确定泛型的数据类型
4.ArrayList list=new ArrayList() [尖括号省略就是默认的Object型]
5.创建集合不使用泛型的
好处:集合不适用泛型,默认的类型就是Object类型,可以存储任意类型的数据
弊端:集合不安全,会发生异常(若发生转换可能会发生转换异常)
6.创建集合使用泛型的
好处:
(1)避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
(2)把运行期异常(代码运行后抛出的异常),提升到了编译期(写代码的时候就会报错)
弊端:泛型是什么类型就只能存储什么类型的数据
7.泛型的定义与使用
(1)定义含有泛型的类的格式:修饰符 class 类名<代表泛型的变量> { }
(2)定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间
格式:修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){
方法体;
}
含有泛型的方法,在 调用方法的时候确定泛型的类型,传递什么类型的参数,泛型就是什么类型
(3)含有泛型的接口
格式:修饰符 interface 接口名 <代表泛型的变量> { }
注意:接口抽象方法不能有方法体必须要靠实现类来实现
使用方法有两种:A:定义接口的实现类,实现接口,指定接口的泛型
public class FXJKImpl1 implements FXJK<String>{}
B:接口使用什么泛型是,实现类就使用什么泛型,类跟着接口走,就相当于定义 了一个含有泛型的类,创建对象的时候确定泛型的类型
public class FXJKImpl2<E> implements FXJK<E> {
@Override
public void method01(E e) {
System.out.println(e);
}
}
创建对象时确定泛型类型;在main方法中的创建对象及调用
FXJKImpl2<String> jk2=new FXJKImpl2();
jk2.method01("实现类2");
8.泛型通配符[在定义的时候不能用]
(1)当使用泛型或者接口时,传递的数据中,泛型的类型不确定,可以通过通配符<?>表示,但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素的自身方法无法使用
(2)不知道使用什么类型来接收的时候,此时可以使用?表示未知通配符,此时只能接收数据不能往该集合中存储数据
(3)使用方式:不嫩恶搞创建对象使用只能作为方法的参数使用
(4)注意:泛型是没有继承概念的方法参数不能直接写<Object>
(5)泛型通配符的高级使用——受限泛型
泛型的上限:格式:类型名称<? extends 类> 对象名称
意义:只能接受该类型及其子类
【?extends E 代表使用的泛型只能是E类型的子类/本身】
泛型的下限:格式:类型名称 <? super 类> 对象名称
意义:只能接收该类型及其父亲类
【? super E 代表使用的泛型只能是E类型的父类/本身】