问题引入
请编写程序,在
ArrayList
中添加3个dog
对象,dog
对象中含有name
和age
,并输出(要求使用getXxx()
)
import java.util.ArrayList;
/*
* 请编写程序,在ArrayList中添加3个dog对象,dog对象中含有name和age,并输出(要求使用getXxx())
*/
public class Generic01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//使用传统方法解决
ArrayList arraylist = new ArrayList();
arraylist.add(new Dog("旺财",10));
arraylist.add(new Dog("发财",10));
arraylist.add(new Dog("旺财",10));
//假如程序员不小心添加了一只猫
arraylist.add(new Cat("招财猫",8)); //--->类型转化异常,dog无法转为cat
//遍历
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) {
super();
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 {
private String name;
private int age;
public Cat(String name, int age) {
super();
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;
}
}
=============================================
旺财-10
发财-10
旺财-10
泛型入门
问题引入的改进版:
@SuppressWarnings({"all"})
告诉编译器忽略所有的警告
import java.util.ArrayList;
/*
* 引入泛型:请编写程序,在ArrayList中添加3个dog对象,dog对象中含有name和age,并输出(要求使用getXxx())
*/
@SuppressWarnings({"all"}) //告诉编译器忽略所有的警告
public class ImproveGeneric01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//使用传统方法解决===>解决泛型
//1. 我们ArrayList<Dog>表示存放到ArrayList集合中的元素为Dog类型
//2. 编译器发现类型不满足要求即可发生报错
//3. 遍历的时候可以直接取出dog类型,无需object类型
//4. public class ArrayList<Dog>() ===>E为泛型,那么Dog->E
ArrayList<Dog1> arraylist = new ArrayList<Dog1>();
arraylist.add(new Dog1("旺财",10));
arraylist.add(new Dog1("发财",10));
arraylist.add(new Dog1("旺财",10));
//假如程序员不小心添加了一只猫
//arraylist.add(new Cat("招财猫",8)); //--->类型转化异常,dog无法转为cat
System.out.println("===============使用泛型===============");
for(Dog1 dog : arraylist) {
System.out.println(dog.getName() + "-" + dog.getAge());
}
}
}
class Dog1 {
private String name;
private int age;
public Dog1(String name, int age) {
super();
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 Cat1 {
private String name;
private int age;
public Cat1(String name, int age) {
super();
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;
}
}
=============================================
旺财-10
发财-10
旺财-10
泛型的好处
- 编译时,检查添加元素的类型,提高了安全性;
- 减少了类型转换的此数,提高效率;
- 不再提示编译警告。
泛型说明
- 泛型又称参数化类型,是
JDK 5.0
出现的新特性,解决数据类型的安全性问题。 - 在类声明或实例化只要指定好需要的具体类型即可。
java
泛型可以保证如果程序在编译时没有发出警告,运行就不会产生问题引入的ClassCastException
异常【类型转化异常】,同时代码更加简洁健壮。- 泛型的作用:可以在类声明时通过一个标识表示类中某个属性的类型,或者时某个方法的返回值的类型,或者是参数类型。
public class Generic03 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person<String> person = new Person<String>("hsp");
person.show();
}
}
//泛型的作用:可以在类声明时通过一个标识表示类中某个属性的类型,
//或者时某个方法的返回值的类型,或者是参数类型。
class Person <E> {
E s; //E表示s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
public Person(E s) { //E也可以是参数类型
super();
this.s = s;
}
public E f() { //也可以在返回类型使用E
return s;
}
public void show() {
System.out.println(s.getClass());
}
}
=============================================
class java.lang.String
泛型的语法
泛型的声明
interface 接口 <T>{}
class类 <K,V,M>{}
比如List、ArrayList
K、V、T
不代表值,而是代表类型。- 任何字母都可以,常用
T
表示,是Type
的缩写。
泛型的实例化
要在类名之后指定类型参数的值(类型)。比如:
题目:创建3个学生对象,放入
HashSet
中学生对象使用,放入到HashMap
中,要求Key
是String name
,Value
就是学生对象,使用两种方式遍历
1. List<String> strList = new ArrayList<String>();
2. Iiterator<Customer> iterator = customers.iterator();
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
* 创建3个学生对象
* 放入HashSet中学生对象使用
* 放入到HashMap中,要求Key是String name,Value就是学生对象
* 使用两种方式遍历
*/
@SuppressWarnings({"all"}) //告诉编译器忽略所有的警告
public class Generic04 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//使用泛型方式给HashSet放入3个学生对象
HashSet<Student> students = new HashSet<Student>();
students.add(new Student("jack",18));
students.add(new Student("jack",20));
students.add(new Student("jack",22));
//遍历
for(Student student: students) {
System.out.println(students);
}
//使用泛型方式给HashSet放入3个学生对象
HashMap<String,Student> hm = new HashMap<String,Student>();
hm.put("tom",new Student("tom",28));
hm.put("tom",new Student("jack",28));
hm.put("tom",new Student("simon",28));
//迭代器遍历
Set<Map.Entry<String,Student>>entries = hm.entrySet();
Iterator<Map.Entry<String,Student>> iterator = entries.iterator();
System.out.println("=============================================");
while(iterator.hasNext()) {
Map.Entry<String,Student> next = iterator.next();
System.out.println(next.getKey() + "-" + next.getValue());
}
}
}
class Student {
String name;
int age;
public Student(String name, int age) {
super();
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<T>{}
,public class HashSet<E>{}
等等中,T、E只能是引用类型。- 给泛型指向数据类型时,要求是引用类型,不能是基本数据类型。
- 在给泛型指定具体类型后,可以传入该类型或者其子类类型。
public class Generic05 {
public static void main(String[] args) {
//在给泛型指定具体类型后,可以传入该类型或者其子类类型。
//因为E指定了A类型,构造器传入了new A()
Pig<A> apig = new Pig<A>(new A());
Pig<A> apig2 = new Pig<A>(new B());
}
}
class A{}
class B extends A{}
class Pig<E> {
E e;
public Pig(E e) {
this.e = e;
}
}
- 泛型的使用形式
List<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list1 = new ArrayList<Integer>();
//实际开发中往往简写
//编译器会进行类型推断(推荐使用)
ArrayList<Integer> list2 = new ArrayList<>()
List<Integer> list2 = new ArrayList<>()
//默认给它的泛型是<E> E就是Object
ArrayList list3 = new ArrayList()等价于
ArrayList<Object> list3 = new ArrayList<>()