泛型说明

泛型说明

泛型的引入

  1. 不能够对加入集合的的数据类型进行约束(不安全)
  2. 遍历的时候,需要进行类型转换,如果集合中的数据量比较大,对效率有影响

不使用泛型

我在添加狗对象的时候,不小心添加了一个猫对象,会报异常的错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.util.*;

public class Test {
public static void main(String[] args) {
ArrayList arrayList=new ArrayList();
arrayList.add(new Dog("asc",15));
arrayList.add(new Dog("ahn",15));
arrayList.add(new Cat("ahn",15));
for (Object o:arrayList){
Dog dog=(Dog) o;
System.out.println(dog.getName()+dog.getAge());
}
}
}
class Dog{
private String name;
private int age;

public Dog(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}
class Cat{
private String name;
private int age;

public Cat(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

}

而当我们使用泛型,就可以直接辨别出来我们加入的对象,并且在遍历的时候,我们可以直接传入Dog对象,而不是再次进行类型转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.util.*;

public class Test {
public static void main(String[] args) {
ArrayList<Dog> arrayList=new ArrayList<Dog>();
arrayList.add(new Dog("asc",15));
arrayList.add(new Dog("ahn",15));
//arrayList.add(new Cat("ahn",15));
for (Dog dog:arrayList){
System.out.println(dog.getName()+dog.getAge());
}
}
}
class Dog{
private String name;
private int age;

public Dog(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}
class Cat{
private String name;
private int age;

public Cat(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

}

image-20220703174055627

image-20220703174109186

泛型理解

泛型又称数据化类型,是jdk5之后出现的新特性,解决数据类型安全性的问题,在类声明或实例化只要指定好需要的具体类型即可。泛型可以保证在程序编译时没有发生警告,运行时就不会产生ClassCastException的异常,同时代码更加简介,健壮。

泛型可以在类声明时通过一个标识表示类中某个属性的类型,或者时某个方法返回值的类型,或者时参数类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.*;

public class Test {
public static void main(String[] args) {
AA<String> aa=new AA<String>("HUAHAU");
System.out.println(aa);
}
}

class AA<E>{
E s;

public AA(E s) {
this.s = s;
}

@Override
public String toString() {
return "AA{" +
"s=" + s +
'}';
}
}

image-20220703174140109

泛型的语法

接口和类都可以拥有泛型,interface接口{},和class类<k,v>{},尖括号里面并不表示值,而是表示类型,常用T来表示,是Type的缩写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.util.*;

public class Test {
public static void main(String[] args) {
Student student=new Student("amin");
Student student1=new Student("amin");
System.out.println(student.hashCode());
System.out.println(student1.hashCode());
HashMap<String,Student> hashMap=new HashMap<String,Student>();
hashMap.put(student.getName(), student);
hashMap.put(student1.getName(), student1);

for (String name: hashMap.keySet()){
System.out.println(name+hashMap.get(name));
}
Set<Map.Entry<String,Student>> entries=hashMap.entrySet();
Iterator<Map.Entry<String,Student>> iterator= entries.iterator();
while (iterator.hasNext()){
Map.Entry<String,Student> next= iterator.next();
System.out.println(next.getKey()+next.getValue());
}

}
}

class Student{
private String name;

public Student(String name) {
this.name = name;
}

public String getName() {
return name;
}
}

image-20220703174210168

泛型的使用细节

  1. 在接口泛型或者类泛型的时候,T或者E只能是引用类型,不可以是基本数据类型
  2. 在指定泛型基本类型后,可以使用其子类的类型。B类继承了student类,那么我们也可以传入子类。!image-20220703174223853
  3. 在实际的开发中,编译器会进行类型推断,所以我们会进行简写,编译器会进行类型推断,比如:HashMap<String,Student> hashMap=new HashMap<>();
  4. 如果我们不使用泛型的<>,默认使用的Object的泛型。HashMap hashMap=new HashMap();也可以将比较方法进行封装

练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import java.util.*;

public class Test {
public static void main(String[] args) {
ArrayList<Employee> arrayList=new ArrayList<>();
arrayList.add(new Employee("花花",563.23,new MyDate(2001,1,3)));
arrayList.add(new Employee("鬼鬼",56375.23,new MyDate(2002,1,3)));
arrayList.add(new Employee("花花",56355.23,new MyDate(2003,1,3)));
System.out.println(arrayList);
Collections.sort(arrayList, new Comparator<>() {
@Override
public int compare(Employee o1, Employee o2) {
int i=o1.getName().compareTo(o2.getName());
if (i!=0){
return i;
}
else{
int j=o1.getBirthday().getYear()-o2.getBirthday().getYear();
if (j!=0){
return j;
}
else {
return o1.getBirthday().getMonth()-o2.getBirthday().getMonth();
}
}

}
});
System.out.println(arrayList);
}
}

class Employee{
private String name;
private double salary;
private MyDate birthday;

public Employee(String name, double salary, MyDate birthday) {
this.name = name;
this.salary = salary;
this.birthday = birthday;
}
@Override
public String toString(){
return name+salary+birthday;
}

public String getName() {
return name;
}

public double getSalary() {
return salary;
}

public MyDate getBirthday() {
return birthday;
}
}
class MyDate{
private int year;
private int month;
private int day;

public int getYear() {
return year;
}

public int getMonth() {
return month;
}

public int getDay() {
return day;
}

public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}

@Override
public String toString() {
return "MyDate{" +
"year=" + year +
", month=" + month +
", day=" + day +
'}';
}
}

image-20220703173913177