容器的泛型
泛型的本质就是“数据类型的参数化”。 我们可以把“泛型”理解为数据类型的一个占位符(形式参数),即告诉编译器,在调用泛型时必须传入实际类型。
好处:增强程序的可读性和安全性
package cn.xjion.pro09;
import java.util.ArrayList;
public class TestGenericity {
public static void main(String[] args) {
//在创建集合对象时,明确集合中所存储的元素的类型
// 定义一个String类型的容器
ArrayList<String> al = new ArrayList<String>();
// 只能存储String类型的数据
al.add("hello");
// al.add(123);报错
// 打印内容
for (String str:al) {
System.out.println(str);
}
}
}
泛型分类
泛型类
package cn.xjion.pro09;
public class MyGenericity<T> {
//T就是一个英文字母,指代泛型,代表一种数据类型
// 声明T类型的变量t
private T t;
//get,set 方法
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public static void main(String[] args) {
// 是什么类型就传什么类型
MyGenericity<String> my1 = new MyGenericity<String>();
MyGenericity<Integer> my2 = new MyGenericity<Integer>();
// 对相应的类型添加相应的数据
my1.setT("hello");
my2.setT(123);
System.out.println(my1.getT());
System.out.println(my2.getT());
}
}
泛型接口
package cn.xjion.pro09;
public interface MyInterface<T> {
}
//实现接口
class MyImplement implements MyInterface<String>{
}
class MyImplement1<T> implements MyInterface<T>{
}
class TestMyInterface{
public static void main(String[] args) {
MyImplement mi = new MyImplement();
MyImplement1<Integer> mi2 = new MyImplement1<Integer>();
}
}
泛型方法
package cn.xjion.pro09;
public class MyMethod<T> {//泛型类
public void show(T t) { //在创建MyMethod类的对象时决定
System.out.println(t);
}
public <Q> void method(Q q) { //在调用method这个方法时明确
System.out.println(q);
}
public <K> void fun(K...k) { //可变参数的泛型方法
for(Object obj:k) {
System.out.println(obj);
}
}
}
package cn.xjion.pro09;
public class TestMyMethod {
public static void main(String[] args) {
MyMethod<String> my = new MyMethod<String>();
my.show("hello"); //在创建类的对象时明确了数据类型为String
//有了泛型方法,解决了参数个数相同的情况下的方法重载
my.method("hello");
my.method(123);
my.method('a');
//可变参数的泛型方法,解决参数的个数不同,类型不同的方法重载
my.fun("hello");
my.fun("hello","world","java");
my.fun(123,456);
}
}
泛型的高级使用_容器中
泛型的上限:使用关键字extends,表示参数化的类型可能是所指定的类型或者是此类型的子类
泛型的下限:使用关键字super进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至Object类
Studnet类
package cn.xjion.pro03;
import cn.xjion.pro09.Person;
public class Student extends Person{
//属性field
int id;
String name;
int age;
// 空构造器
public Student(){
}
//重写toString
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
//构造器
public Student(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
}
Person类
package cn.xjion.pro09;
// Person类实现Person型的Comperable接口
public class Person implements Comparable<Person>{
// 属性
private String name;
private int age;
// get,set方法
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;
}
// 带参构造方法
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
//空构造器
public Person() {
super();
// TODO Auto-generated constructor stub
}
// 重写hashCode和equals方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// 重写toString
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
// 重写compareTo方法
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
return 0;
}
}
实现
package cn.xjion.pro09;
import java.util.ArrayList;
import cn.xjion.pro03.Student;
public class TestGener {
public static void main(String[] args) {
// 创建集合对象,同时明确了对象只能是Person类型
ArrayList<Person> a1 = new ArrayList<Person>();
Person p1 = new Person("xjion",20);
Person p2 = new Person("sarry",25);
Person p3 = new Person("jack",18);
// 添加到集合中
a1.add(p1);
a1.add(p2);
a1.add(p3);
// 需要遍历集合
print(a1);
// 创建集合对象,同时明确了对象只能是Student类型
ArrayList<Student> al2 = new ArrayList<Student>();
Student stu1 = new Student(1001,"merny",20);
Student stu2 = new Student(2112,"anico",18);
// 添加到集合
al2.add(stu1);
al2.add(stu2);
// 打印
print(al2);
// 调用show方法
System.out.println("-------------------------");
show(a1);
show(al2);
ArrayList<Object> alObject = new ArrayList<Object>();
Object ob1 = new Object();
Object obj2 = new Object();
alObject.add(ob1);
alObject.add(obj2);
show(alObject);
}
// Person及Person的子类的打印遍历
public static void print(ArrayList<? extends Person> al){
for (Person person : al) {
System.out.println(person);
}
}
public static void show(ArrayList<? super Student> al){
for (Object object : al) {
System.out.println(object);
}
}
}
package cn.xjion.pro09;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.TreeMap;
import java.util.TreeSet;
public class Test2 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("hello");
LinkedList<Integer> linkedList = new LinkedList<Integer>();
linkedList.add(123);
//存储自定义对象时,要求Person类重写hashCode()及equals()方法
HashSet<Person> hs = new HashSet<Person>();
//Person对象具备比较规则,可以是内部比较器,也可以是外部比较器
TreeSet<Person> treeSet = new TreeSet<Person>();
HashMap<String,Integer> hm = new HashMap<String,Integer>();
hm.put("hello", 123);
HashMap<Person,String> hm2 = new HashMap<Person,String>();
Person p1 = new Person("marry",20);
hm2.put(p1, p1.getName());
TreeMap<Person,Integer> tm = new TreeMap<Person,Integer>();
tm.put(p1, p1.getAge());
//泛型只在编译期间起作用
}
}