泛型
使用传统方法分析:
- 不能对加入到集合ArrayList中的数据类型进行约束(不安全)
- 遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响
泛型的好处:
- 编译时,检查添加元素的类型。提高了安全性
- 减少了类型转换的次数,提高效率
不使用泛型
Dog->Object->Dog//放入到ArrayList会先转成Object,在取出时还需要转换成Dog
使用泛型
Dog->Dog->Dog//放入时和取出时不需要类型转换,提高效率
/*
1.请编写程序,在 ArrayList 中,添加 3 个 Dog 对象
2.Dog 对象含有 name 和 age, 并输出 name 和 age (要求使用 getXxx())
3.使用泛型来完成代码
*/
public class Generic02 {
public static void main(String[] args) {
//ArrayList<Dog>表示存放到ArrayList集合中的元素是Dog类型
//如果编译器发现添加的类型不满足要求,就会报错
//在遍历的时候,可以直接取出 Dog 类型而不是 Object
//public class ArrayList<E> {};把E称为泛型,那么Dog->E
ArrayList<Dog> arrayList = new ArrayList<Dog>();
arrayList.add(new Dog("旺财", 10));
arrayList.add(new Dog("发财", 1));
arrayList.add(new Dog("小黄", 5));
//arrayList.add(new Cat("招财猫", 8));报错
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 void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Cat { //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 void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
泛(广泛)型(类型)=>Integer,String,Dog
泛型又称参数化类型,是JDK5.0出现的新特性,解决数据类型的安全性问题
在类声明或实例化时只需要指定好需要的具体类型即可。
Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮
泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值类型,或者是参数类型。
public class Generic03 {
public static void main(String[] args) {
Person<String> stringPerson = new Person<String>("北京你好");
stringPerson.show();//class java.lang.String
//Person类:E可以被赋予任何数据类型,需要S是什么数据类型就设置什么数据类型,此处为String
Person<Integer> person2 = new Person<Integer> (100);
person2.show();//lass java.lang.Integer
}
}
class Person<E>{
E s;//E表示s的数据类型,该数据类型是在定义Person对象时指定,即在编译期间就确定E是什么类型
public Person(E s) {//E也可以是参数类型
this.s = s;
}
public E f(){//返回类型使用E
return s;
}
public void show() {
System.out.println(s.getClass());//显示 s 的运行类型
}
}
泛型语法
泛型的声明:
interface 接口
/比如:List,ArrayList
说明:其中T,K,V不代表值,而是表示类型;
任意字母都可以。常用T表示,是Type的缩写
泛型的实例化:
要在类名后面指定类型参数的值。如:
List
Iterator
public class GenericExercise {
public static void main(String[] args) {
//使用泛型方式给HashSet放入3个学生对象
HashSet<Student> students = new HashSet<Student> ();
students.add(new Student("jack",18));
students.add(new Student("tom",28));
students.add(new Student("mary",19));
//遍历
for(Student student:students){
System.out.println(student);
}
//使用泛型给HashMap放入三个学生对象
HashMap<String,Student> hm = new HashMap<String,Student>();
/*
public class HashMap<K,V> {}
*/
hm.put("milan",new Student("milan",38));
hm.put("smith",new Student("smith",48));
hm.put("amy",new Student("amy",20));
//迭代器EntrySet
Set<Map.Entry<String, Student>> entries = hm.entrySet();
/*
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}
*/
Iterator<Map.Entry<String, Student>> iterator = entries.iterator();
/*
public final Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();
}
*/
while(iterator.hasNext()){
Map.Entry<String, Student> next = iterator.next();
System.out.println(next.getKey() + "===>" + next.getValue());
}
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
泛型使用的注意事项和细节
- interface List
{},public class HashSet {}等等
说明:T,E只能是引用类型,不能说基本数据类型
List
List
- 在指定泛型具体类型后,可以传入该类型或者其子类类型
- 泛型使用形式
List
List
- 如果我们这样写ArrayList list3 = new ArrayList();默认给它的泛型是[
E就是Object],等价于ArrayList
浙公网安备 33010602011771号