1.为什么引入泛型
不引入泛型产生的问题:
(1)List l=new List()不指定list的元素的类型,什么对象都可以放入List中,并且都会转换成object类型。在通过get()方法获取集合中的元素时必须进行强制类型的转换,不仅繁琐而且容易出现ClassCaseException异常。Map也会遇到同样的问题。
(2)list<String>l=new List<String>()指定元素类型,如果添加其他类型的数据,将出现编译错误,这在一定程度上保证了代码的安全性。同时由于制定了数据类型,在获取集合的数据时候不需要再进行强制的类型转换。但是,只指定一种元素类型,代码的重用性就降低了。
引入泛型的好处
(1)存储数据时候进行严格的检查,确保只有合适类型的对象才能存储到集合
(2)从集合中检索对象时,减少了强制类型转换
(3)提高了代码的重用性
2.泛型的本质
泛型的本质是参数化类型,就是把数据类型作为参数,可以在具体使用的时候指定具体的类型。
3.泛型类、泛型接口、泛型方法
3.1泛型类
public class Container<K, V> {
private K key;
private V value;
public Container(K k, V v) {
key = k;
value = v;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
在编译期,是无法知道K
和V
具体是什么类型,只有在运行时才会真正根据类型来构造和分配内存。只是普通的类,去掉了具体的参数类型
3.2泛型接口
在泛型接口中,生成器是一个很好的理解,看如下的生成器接口定义:
public interface Generator<T> {
public T next();
}
然后定义一个生成器类来实现这个接口:
public class FruitGenerator implements Generator<String> {
private String[] fruits = new String[]{"Apple", "Banana", "Pear"};
@Override
public String next() {
Random rand = new Random();
return fruits[rand.nextInt(3)];
}
}
实现类给接口具体的参数类型
3.3泛型函数
泛型函数要好好理解
public static <T> void out(T t) {
System.out.println(t);
}
3.4
实例化泛型
4.实例
package generic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Collections;
class Student {
String name;
String age;
String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
class Grade<T, V, K> {
HashMap<K, V> grades = new HashMap<K, V>();
ArrayList<T> students = new ArrayList<T>();
}
public class Generic {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 创建三个学生
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
s1.setName("张三丰");
s1.setSex("男");
s1.setAge("7");
s2.setName("杨过");
s2.setSex("男");
s2.setAge("9");
s3.setName("小龙女");
s3.setSex("女");
s3.setAge("8");
// 实例化年级
Grade g = new Grade<Student, String, Student>();
g.students.add(s1);
g.students.add(s2);
g.students.add(s3);
g.grades.put("一年级", g.students);
System.out.println("输入年级:");
String grade = sc.next();
if (g.grades.containsKey(grade)) {
ArrayList al = (ArrayList) g.grades.get(grade);
Iterator it = al.iterator();
System.out.println("一年级的学生列表:");
while (it.hasNext()) {
Student s = (Student) it.next();
System.out.println(s.getName() + " " + s.getSex() + " " + s.getAge());
}
}
}
}