/**
* Created by PengZhiLin on 2021/8/3 10:16
*/
public class Test {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合元素的类型为String类型
Collection col = new ArrayList<>();
// 往集合中添加元素
col.add("谢霆锋");
col.add("王宝强");
col.add("贾乃亮");
col.add("陈羽凡");
// 增强for循环
for (String name : col) {
System.out.println("name:" + name);
//col.add("潘粤明");// 报并发修改异常
//col.remove(name);// 报并发修改异常
}
System.out.println("--------------------");
// 创建String类型的数组,并存储元素
String[] arr = {"陈冠希", "罗志祥", "吴签", "林俊杰"};
// 增强for循环
for (String name : arr) {
System.out.println("name:" + name);
}
}
}
第三章 泛型
3.1 泛型的概述
概述: JDK5之后,新增了泛型(Generic)语法,可以在类、接口或方法中预支地使用未知的类型
简而言之: 泛型其实就是表示一种未知的数据类型,在使用的时候确定其具体数据类型
表示方式: <泛型变量> 泛型变量任意字母
泛型的好处:
将运行时期的ClassCastException,转移到了编译时期变成了编译失败
避免了类型转换的麻烦
案例:
集合不使用泛型
可能会发生类型转换异常
避免类型转换异常,就需要先做类型判断,再转型--->比较麻烦
/**
* Created by PengZhiLin on 2021/8/3 10:44
*/
public class Test {
public static void main(String[] args) {
// 创建Collection集合,不使用泛型
Collection col = new ArrayList();
// 往集合中添加元素
col.add("张三");
col.add(18);
col.add("中国北京");
col.add(3.14);
System.out.println("col:" + col);
// 循环遍历
for (Object obj : col) {
// 获取字符串元素的长度,打印输出
//String str = (String)obj;
//System.out.println("字符串元素的长度:"+str.length());
// 避免类型转换异常
if (obj instanceof String){
String str = (String)obj;
System.out.println("字符串元素的长度:"+str.length());
}
}
}
}
集合使用泛型
概述:指定泛型的具体数据类型----->(只能是引用数据类型)
/**
* Created by PengZhiLin on 2021/8/3 10:44
*/
public class Test {
public static void main(String[] args) {
// 创建Collection集合,使用泛型
Collection col = new ArrayList();
// 往集合中添加元素
col.add("张三");
//col.add(18);// 编译报错
col.add("中国北京");
//col.add(3.14);// 编译报错
System.out.println("col:" + col);
// 循环遍历
/* for (Object obj : col) {
// 获取字符串元素的长度,打印输出
//String str = (String)obj;
//System.out.println("字符串元素的长度:"+str.length());
// 避免类型转换异常
if (obj instanceof String){
String str = (String)obj;
System.out.println("字符串元素的长度:"+str.length());
}
}*/
for (String str : col) {
System.out.println("字符串元素的长度:"+str.length());
}
}
}
3.2 定义和使用含有泛型的类
定义含有泛型的类
格式:
public class 类名<泛型变量>{
}
泛型变量: 可以是任意字母,eg: A,B,E,...a,b,....;一般写E
案例
/**
* Created by PengZhiLin on 2021/8/3 10:54
*/
public class MyGenericClass {
// 成员变量
E e;// 未知类型的成员变量
// 成员方法
public E method(E e){
return e;
}
}
使用含有泛型的类
创建含有泛型的类的对象的时候,指定泛型的具体数据类型(只能是引用数据类型)
案例
/**
* Created by PengZhiLin on 2021/8/3 11:02
*/
public class Test {
public static void main(String[] args) {
// 创建含有泛型的类的对象的时候,指定泛型的具体数据类型(只能是引用数据类型)
// 创建MyGenericClass对象,指定泛型的具体数据类型为String
MyGenericClass mc1 = new MyGenericClass<>();
// 访问MyGenericClass类的成员变量
mc1.e = "itheima";
System.out.println("e:" + mc1.e);
// 访问MyGenericClass类的成员方法
String res1 = mc1.method("itcast");
System.out.println("res1:"+res1);
System.out.println("---------------");
// 创建MyGenericClass对象,指定泛型的具体数据类型为Integer
MyGenericClass mc2 = new MyGenericClass<>();
// 访问MyGenericClass类的成员变量
mc2.e = 100;
System.out.println("e:" + mc2.e);
// 访问MyGenericClass类的成员方法
Integer res2 = mc2.method(200);
System.out.println("res2:"+res2);
}
}
3.3 定义和使用含有泛型的接口
定义含有泛型的接口
格式:
public interface 接口名<泛型变量>{
}
// 泛型变量:可以是任意字母,一般写E
案例:
/**
* Created by PengZhiLin on 2021/8/3 11:08
*/
public interface MyGenericInterface{
E method1(E e);
}
使用含有泛型的接口
方式一: 实现类实现接口的时候,确定接口泛型的具体数据类型
格式:
public class 类名 implements 接口名<具体的引用数据类型>{}
案例:
/**
* Created by PengZhiLin on 2021/8/3 11:11
*/
public class MyImp1 implements MyGenericInterface {
@Override
public String method1(String s) {
return "String字符串";
}
}
/**
* Created by PengZhiLin on 2021/8/3 11:13
*/
// 实现类实现接口的时候不指定接口泛型的具体数据类型
public class MyImp2 implements MyGenericInterface{
@Override
public E method1(E e) {
return e;
}
}
public class Test {
public static void main(String[] args) {
// 创建MyImp1对象
MyImp1 imp1 = new MyImp1();
String res1 = imp1.method1("itheima");
System.out.println("res1:"+res1);
// 创建MyImp2对象,指定泛型的具体数据类型为String
MyImp2 imp2 = new MyImp2<>();
String res2 = imp2.method1("itcast");
System.out.println("res2:"+res2);
// 创建MyImp2对象,指定泛型的具体数据类型为Integer
MyImp2 imp3 = new MyImp2<>();
Integer res3 = imp3.method1(100);
System.out.println("res3:"+res3);
}
}
/**
* Created by PengZhiLin on 2021/8/3 11:22
*/
public class MyGenericMethod {
public T method(T t){
return t;
}
}
使用含有泛型的方法
调用含有泛型方法的时候,确定泛型的具体数据类型
案例:
/**
* Created by PengZhiLin on 2021/8/3 11:23
*/
public class Test {
public static void main(String[] args) {
// 调用含有泛型方法的时候,确定泛型的具体数据类型
Integer res1 = MyGenericMethod.method(100);
System.out.println("res1:"+res1);
String res2 = MyGenericMethod.method("itheima");
System.out.println("res2:"+res2);
}
}
Collection<?> col3 = new ArrayList();// 正确的
Collection<?> col4 = new ArrayList();//正确的
Collection<?> col5 = new ArrayList
注意:
如果使用了泛型通配符,那么该集合变量元素类型默认是Object类型
如果使用了泛型通配符,那么该集合变量只能取元素,无法增删元素
案例:
/**
* Created by PengZhiLin on 2021/8/3 11:46
*/
public class Test {
public static void main(String[] args) {
// 泛型本身不存在继承关系,不可以给已指定泛型的变量接收有其他泛型类型的对象
//Collection
通配符高级使用----受限泛型
上限:
格式: <? extends 类名>
表示: 只接受泛型是该类类型或者该类的子类类型
下限:
格式: <? super 类名>
表示: 只接受泛型是该类类型或者该类的父类类型
案例:
案例:
/**
* Created by PengZhiLin on 2021/8/3 12:02
*/
public class Test {
public static void main(String[] args) {
// 创建ArrayList集合,限制集合元素的类型为Object
ArrayList list1 = new ArrayList<>();
// 创建ArrayList集合,限制集合元素的类型为String
ArrayList list2 = new ArrayList<>();
// 创建ArrayList集合,限制集合元素的类型为Number
ArrayList list3 = new ArrayList<>();
// 创建ArrayList集合,限制集合元素的类型为Integer
ArrayList list4 = new ArrayList<>();
//method1(list1);// 编译报错
//method1(list2);// 编译报错
method1(list3);
method1(list4);
System.out.println("---------------");
method2(list1);
//method2(list2);// 编译报错
method2(list3);
//method2(list4);// 编译报错
}
// 定义一个方法,接收泛型为Number类型或者其子类类型的ArrayList集合
public static void method1(ArrayList<? extends Number> list){
}
// 定义一个方法,接收泛型为Number类型或者其父类类型的ArrayList集合
public static void method2(ArrayList<? super Number> list){
}
}
public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
public E get(int index):返回集合中指定位置的元素。
public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
List集合特有的方法都是跟索引相关,我们在基础班都学习过。
List接口新增常用方法的使用
/**
* Created by PengZhiLin on 2021/8/3 15:41
*/
public class Test {
public static void main(String[] args) {
// 创建List集合,限制集合元素的类型为String类型
List list = new ArrayList<>();
// 往集合中添加元素
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("张敏");
//list:[林青霞, 张曼玉, 王祖贤, 张敏]
System.out.println("list:" + list);
// - `public void add(int index, E element)`: 将指定的元素,添加到该集合中的指定位置上。
// 往索引为1的位置添加一个元素:温碧霞
list.add(1, "温碧霞");
//list:[林青霞, 温碧霞, 张曼玉, 王祖贤, 张敏]
System.out.println("list:" + list);
//- `public E get(int index)`:返回集合中指定位置的元素。
// 获取索引为3的元素
System.out.println("索引为3的元素:"+list.get(3));// 王祖贤
//- `public E remove(int index)`: 移除列表中指定位置的元素, 返回的是被移除的元素。
// 删除索引为1的元素
String removeE = list.remove(1);
System.out.println("被删除的元素:"+removeE);// 温碧霞
// list:[林青霞, 张曼玉, 王祖贤, 张敏]
System.out.println("list:" + list);
//- `public E set(int index, E element)`:用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
// 把张曼玉换成邱淑贞
String setE = list.set(1, "邱淑贞");
System.out.println("被替换的元素:"+setE);// 张曼玉
// list:[林青霞, 邱淑贞, 王祖贤, 张敏]
System.out.println("list:" + list);
}
}
注意: 如果集合元素为Integer类型,那么删除的时候优先根据索引删除
/**
* Created by PengZhiLin on 2021/8/3 15:48
*/
public class Test2 {
public static void main(String[] args) {
// 创建List集合,限制集合中元素的类型为Integer类型
List list = new ArrayList<>();
// 添加元素
list.add(1);
list.add(2);
list.add(3);
list.add(4);
//删除之前:[1, 2, 3, 4]
System.out.println("删除之前:" + list);
// 删除索引为2的元素----如果集合元素为Integer类型,那么删除的时候优先根据索引删除
list.remove(2);
//删除之后:[1, 2, 4]
System.out.println("删除之后:" + list);
// 删除2这个元素
//list.remove(1);// 根据索引删除 remove(int index)
Integer i = 2;
list.remove(i);// 2 remove(Object obj)
//删除之后:[1, 4]
System.out.println("删除之后:" + list);
}
}
5.3 List的子类
ArrayList集合: 底层采用的是数组结构,查询快,增删慢
方法: 来自Collection,List
LinkedList集合; 底层采用的是链表结构,查询慢,增删快
方法: 来自Collection,List,LinkedList特有的方法
特有的方法:
public void addFirst(E e):将指定元素插入此列表的开头
public void addLast(E e):将指定元素添加到此列表的结尾
public E getFirst():返回此列表的第一个元素
public E getLast():返回此列表的最后一个元素
public E removeFirst():移除并返回此列表的第一个元素
public E removeLast():移除并返回此列表的最后一个元素
public E pop():从此列表所表示的堆栈处弹出一个元素
public void push(E e):将元素推入此列表所表示的堆栈
案例:
/**
* Created by PengZhiLin on 2021/8/3 15:56
*/
public class Test {
public static void main(String[] args) {
// 创建LinkedList集合,限制集合元素的类型为String
LinkedList list = new LinkedList<>();
// 往集合中添加元素
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("张敏");
System.out.println("list:" + list);
//public void addFirst(E e):将指定元素插入此列表的开头
//public void addLast(E e):将指定元素添加到此列表的结尾
list.addFirst("温碧霞");
list.addLast("邱淑贞");
System.out.println("list:" + list);
//public E getFirst():返回此列表的第一个元素
//public E getLast():返回此列表的最后一个元素
String firstE = list.getFirst();
String lastE = list.getLast();
System.out.println("第一个元素:"+firstE);// 温碧霞
System.out.println("最后一个元素:"+lastE);// 邱淑贞
//public E removeFirst():移除并返回此列表的第一个元素
//public E removeLast():移除并返回此列表的最后一个元素
String removeFirst = list.removeFirst();
String removeLast = list.removeLast();
System.out.println("被删除的第一个元素:"+removeFirst);// 温碧霞
System.out.println("被删除的最后一个元素:"+removeLast);// 邱淑贞
System.out.println("list:" + list);// [林青霞, 张曼玉, 王祖贤, 张敏]
//public E pop():从此列表所表示的堆栈处弹出一个元素====>removeFirst()
//public void push(E e):将元素推入此列表所表示的堆栈==>addFirst()
String popE = list.pop();
System.out.println("弹出的第一个元素:" + popE);// 林青霞
list.push("李嘉欣");
System.out.println("list:" + list);// [李嘉欣, 张曼玉, 王祖贤, 张敏]
}
}