1.泛型的概述和好处
是一种把类型明确的工作推迟到创建对象或调用方法时才去明确的特殊的类型。
格式:<数据类型> 这里的数据类型是引用数据类型,泛型可以定义在类,接口,方法上。
(1): 把运行时期的问题提前到了编译期间
(2): 避免了强制类型转换
(3):优化了程序设计,解决了黄色警告线
注意:泛型只在编译期有效 但在运行期就擦除了
package com.westmo.demo9;
import java.util.ArrayList;
public class MyDemo5 {
public static void main(String[] args) {
Student1 student1 = new Student1("李明", 12, '男');
Student1 student2 = new Student1("小花", 15, '女');
Student1 student3 = new Student1("小李", 18, '女');
ArrayList<Student1> list = new ArrayList();
//ArrayList<Object> objects = new ArrayList();
list.add(student1);
list.add(student2);
list.add(student3);
for (int i = 0; i < list.size(); i++) {
Student1 student = (Student1) list.get(i);
System.out.println(student);
}
}
}
package com.westmo.demo9;
public class Student1 {
private String name;
private int age;
private char sex;
public Student1(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Student1{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
2.泛型类的概述和使用
泛型类:把泛型定义在类中。
定义格式:public class 类名<泛型类型1,…>{} 泛型类型必须是引用类型
案例演示
package com.westmo.demo10;
public class MyDemo4 {
public static void main(String[] args) {
MyTest1<String, Integer, Double> stringIntegerDoubleMyTest1 = new MyTest1<>("123",12,12.3);
MyTest1<Character, Boolean, Long> characterBooleanLongMyTest1 = new MyTest1<>('q', true, (long) 123);
String s = stringIntegerDoubleMyTest1.toString();
String s1 = characterBooleanLongMyTest1.toString();
System.out.println(s);
System.out.println(s1);
}
}
package com.westmo.demo10;
public class MyTest1<Y,J,G> {
private Y y;
private J j;
private G g;
public MyTest1(Y y, J j, G g) {
this.y = y;
this.j = j;
this.g = g;
}
@Override
public String toString() {
return "MyTest1{" +
"y=" + y +
", j=" + j +
", g=" + g +
'}';
}
}
3.泛型方法的概述和使用
泛型方法:把泛型定义在方法上
格式:public <泛型类型> 返回类型 方法名(泛型类型 变量名){}
案例演示
package com.westmo.demo10;
public class MyDemo5 {
public static void main(String[] args) {
show(12);
}
public static <T> void show(T num){
System.out.println(num);
}
}
4.泛型接口的概述和使用
泛型接口:把泛型定义在接口上
格式:public interface 接口名<泛型类型>{}
案例演示
package com.westmo.demo10;
public class MyDemo6 {
public static void main(String[] args) {
Mytest mytest = new Mytest();
mytest.test("qwe");
}
}
class Mytest implements Mydemo<String>{//当定义类来实现这个接口时,可以明确接口中泛型的具体类型
@Override
public void test(String y) {
System.out.println(y);
}
}
interface Mydemo<T>{
void test(T t);
}
5.泛型高级之通配符
泛型通配符:<?> 任意类型
(1)<? extends E>:向下限定(E及其子类)
(2)<? super E>:向上限定(E及其父类)
ArrayList<? extends Student> students = new ArrayList<Student1>();
ArrayList<? extends Student> students1 = new ArrayList<Student>();//只能时Student的本身或子类
ArrayList<? super Student1> objects = new ArrayList<Student>();//只能时Student1的本身或父类
ArrayList<? super Student1> objects1 = new ArrayList<Object>();
案例演示
package com.westmo.demo10;
public class MyDemo7 {
public static void main(String[] args) {
//确定了泛型实例化对象只能是String类或者它的子类
Student<? extends String> stringStudent = new Student<String>();
//Student<? extends Integer> integerStudent = new Student<Object>();报错
stringStudent.test();
//确定话了泛型实例化对象只能是Character类或者它的父类
Student<? super Character> characterStudent = new Student<Object>();
characterStudent.test();
}
}
class Student<T> {
public void test(){
System.out.println("123");
}
}
6.增强for
- 概述:简化数组和集合Collection的遍历
- 格式:for(元素数据类型 变量 :数组或集合Collection集合){使用变量即可}
- 案例演示(ArrayList存出自定义对象并用增强for遍历)
package com.westmo.demo10;
import java.util.ArrayList;
public class MyDemo8 {
public static void main(String[] args) {
MyTestdemo myTest = new MyTestdemo("张三", 12, '男');
MyTestdemo myTest1 = new MyTestdemo("李四", 23, '女');
ArrayList<MyTestdemo> arrayList = new ArrayList<>();
arrayList.add(myTest);
arrayList.add(myTest1);
for (MyTestdemo test : arrayList) {
System.out.println(test);
}
for (int i = 0; i < arrayList.size(); i++) {
MyTestdemo myTestdemo = arrayList.get(i);
System.out.println(myTestdemo);
}
int arr[]={1,2,3,4,5,7};
for (int i : arr) {
System.out.println(i);
}
}
}
package com.westmo.demo10;
public class MyTestdemo {
private String name;
private int age;
private char sex;
public MyTestdemo(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "MyTestdemo{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
7.可变参数
- 概述:定义方法的时候不知道定义多少个参数
- 格式:修饰符 返回值类型 方法名(数据类型…变量名)
- 注意事项:这里的变量其实是一个数组,如果一个方法有可变参数,并且有多个参数,那么可变参数一定是最后一个。
- 案例演示
package com.westmo.demo10;
public class MyDemo9 {
public static void main(String[] args) {
//现在要编写一个求和的功能,但是不知道有几个参数,在调用的时候才知道有几个参数,
int a=10,b=20,c=30;
int test = test(a, b, c);
System.out.println(test);
int d=10,e=10,f=10,g=20;
int test1 = test(a, b, c, d, e, f, g);
System.out.println(test1);
}
private static int test(int a,int ...b){
int sum=0;
for (int i : b) {
sum=sum+i;
}
return sum+a;
}
}
8.ArrayList集合工具中的asList()方法
- 用途:将数组转为集合
- 注意:数组转为集合后集合的长度是不可变的,不能转换后的集合
- 案例演示
package com.westmo.demo10;
import java.util.Arrays;
import java.util.List;
public class MyDemo10 {
public static void main(String[] args) {
int arr[]={2,3,4,51,2,3,4,5,8};
List<int[]> ints = Arrays.asList(arr);
System.out.println(ints);//输出[[I@1540e19d],集合中的元素是一个数组类型
Integer integer[]={2,3,4,51,2,3,4,5,8};
List<Integer> integers = Arrays.asList(integer);
System.out.println(integers);//输出[2, 3, 4, 51, 2, 3, 4, 5, 8],集合中元素是Integer类型
}
}
- 原因分析
asList源码
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
(1)通过asList源码我们可以看到,它接受一个泛型化的可变参数列表,当传入一个基本类型数据的数组的时候时,它会把这个基本类型数据的数组当作一个参数传入,然后返回一个新的ArrayList,其中a就是这个基本类型的数组,所以可变参数列表就只接受了一个参数就是数组。
(2)当传入一个包装类型对象数组的时候,其中数组的每一个元素都是一个对象,那么这个可变参数列表就传入 五个对象类型Integer,还有一点是因为基础数据类型是不能被泛型化的,所以才会导致上上面的结果。
9.集合嵌套
- 需求:我们班有学生,每一个学生是不是一个对象。所以我们可以使用一个集合表示我们班级的学生。ArrayList
但是呢,我们旁边是不是还有班级,每个班级是不是也是一个ArrayList。
而我现在有多个ArrayList。也要用集合存储,怎么办呢? - 案例演示
package com.westmo.demo10;
import java.util.ArrayList;
public class myDemo11 {
public static void main(String[] args) {
MyTestdemo myTestdemo1 = new MyTestdemo("王五", 33, '女');
MyTestdemo myTestdemo2 = new MyTestdemo("李四", 13, '男');
MyTestdemo myTestdemo3 = new MyTestdemo("小明", 17, '女');
MyTestdemo myTestdemo4 = new MyTestdemo("小三", 19, '女');
ArrayList<MyTestdemo> arrayList1 = new ArrayList<>();
arrayList1.add(myTestdemo1);
arrayList1.add(myTestdemo2);
ArrayList<MyTestdemo> arrayList2 = new ArrayList<>();
arrayList2.add(myTestdemo3);
arrayList2.add(myTestdemo4);
ArrayList<ArrayList<MyTestdemo>> arrayLists = new ArrayList<>();
arrayLists.add(arrayList1);
arrayLists.add(arrayList2);
//遍历
for (ArrayList<MyTestdemo> arrayList : arrayLists) {
for (MyTestdemo myTestdemo : arrayList) {
System.out.println(myTestdemo);
}
}
for (int i = 0; i < arrayLists.size(); i++) {
ArrayList<MyTestdemo> arrayList = arrayLists.get(i);
for (int i1 = 0; i1 < arrayList.size(); i1++) {
MyTestdemo myTestdemo = arrayList.get(i1);
System.out.println(myTestdemo);
}
}
}
}