为什么要使用泛型?
当我们对于对象的类型不知道的时候可以使用泛型(类型占位符)进行占位。
定义泛型类实质就是将现在代码中所有的特定类型换为类型占位符
package com.fanxing.o;
public class Person<T> {
//private String name;//这里已经知道name要使用String类型了,如果不知道呢?
private T name1;
private T age;
public T getName1() {
return name1;
}
public void setName1(T name1) {
this.name1 = name1;
}
public T getAge() {
return age;
}
public void setAge(T age) {
this.age = age;
}
public Person(T name1, T age) {
this.name1 = name1;
this.age = age;
}
@Override
public String toString() {
return "test1{" +
"name1=" + name1 +
", age=" + age +
'}';
}
public static void main(String[] args) {
Person t=new Person("sfds",15);
Person<String> t1=new Person<String>("string","123");
}
}
使用泛型之后的变化:
Mydate:定义了私有属性 year month, day
Employee
package com.fanxing.exer;
public class Employee implements Comparable<Employee>{//Comparable设计比较,要比较谁,泛型就填谁的
private String name;
private int age;
private Mydate birthday;
public Employee(String name, int age, Mydate birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
public Employee() {
}
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 Mydate getBirthday() {
return birthday;
}
public void setBirthday(Mydate birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +//调用自己的toString,输出年月日
'}';
}
//按照name排名
//改为泛型之前
/* @Override
public int compareTo(Object o) {
if(o instanceof Employee){//判断o是否为Employee的一个实例或对象
Employee e=(Employee)o;
return this.name.compareTo(e.name);
}
return 0;
}*/
//使用泛型之后,不用再判断,直接return
@Override
public int compareTo(Employee o) {
return this.name.compareTo(o.name);
}
}
package com.fanxing.exer;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class EmployeeTest {
//按照生日日期先后排序
public void test2(){
TreeSet set=new TreeSet(new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
if(o1 instanceof Employee && o2 instanceof Employee){//判断o1,o2是否为Employee的一个实例或对象
/* Employee e1= o1;
Employee e2= o2;*/
Mydate b1 = o1.getBirthday();
Mydate b2 = o2.getBirthday();
//方式一
//比较年
int sumYear=b1.getYear()-b2.getYear();
if(sumYear!=0){
return sumYear;
}
//比较月
int summonth=b1.getMonth()-b2.getMonth();
if(summonth!=0){
return summonth;
}
//比较日
return b1.getDay()-b2.getDay();
}
//return 0;
throw new RuntimeException("传入的数据类型不一样");
}
});
Employee e1=new Employee("ldh",55,new Mydate(1964,12,24));
Employee e2=new Employee("hg",50,new Mydate(1974,3,14));
Employee e3=new Employee("zj",45,new Mydate(1969,4,28));
Employee e4=new Employee("zxc",51,new Mydate(1970,6,5));
Employee e5=new Employee("zgr",40,new Mydate(1970,6,25));
set.add(e1);
set.add(e2);
set.add(e3);
set.add(e4);
set.add(e5);
Iterator iterator=set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
//自然排序
public void test(){
TreeSet<Employee> set=new TreeSet<Employee>();//将泛型设为Employee是因为在下边set.add添加的变量是Employee类型的
Employee e1=new Employee("ldh",55,new Mydate(1964,12,24));
Employee e2=new Employee("hg",50,new Mydate(1974,3,14));
Employee e3=new Employee("zj",45,new Mydate(1969,4,28));
Employee e4=new Employee("zxc",51,new Mydate(1972,5,5));
Employee e5=new Employee("zgr",40,new Mydate(1970,6,25));
set.add(e1);
set.add(e2);
set.add(e3);
set.add(e4);
set.add(e5);
/*//增强for循环
for(Object obj:set){
System.out.println(obj);
}*/
//iterator迭代器
Iterator<Employee> iterator = set.iterator();
while (iterator.hasNext()){
Employee next = iterator.next();
System.out.println(next);
}
}
public static void main(String[] args) {
EmployeeTest t=new EmployeeTest();
System.out.println("按照名字排序");
t.test();
System.out.println("按照生日排序");
t.test2();
}
}
举例:
package com.fanxing.juli;
public class Customer {//此类对应数据库中的Customer表
}
package com.fanxing.juli;
public class CustomerDAO extends DAO<Customer>{//专门操作Customer表
}
package com.fanxing.juli;
import java.util.List;
public class DAO<T> {
//增
public void add(T t){}
//删
public void remove(int index){
//return 0;
}
//修
public void update(int index , T t){
}
//查一条记录
public void getIndex(int index){
}
//查多条记录
public List<T> getForList(int index){
return null;
}
}
package com.fanxing.juli;
public class CustomerTest {
public void test(){
CustomerDAO c=new CustomerDAO();
c.add(new Customer());
}
}
例子2:
package com.fanxing.o;
public class P1<T> {//泛型普通方法
public void test(T name){
System.out.println(name+"主旨演讲3");
}
//静态泛型方法中的类型占位符与类中的泛型占位符没有关系
public static <W> void test1(W name){
System.out.println(name+":静态方法主旨演讲3");
}
}
package com.fanxing.o;
public class Person<T> {
//private String name;//这里已经知道name要使用String类型了,如果不知道呢?
private T name;
private T age;
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
public T getAge() {
return age;
}
public void setAge(T age) {
this.age = age;
}
public Person(T name, T age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "test1{" +
"name=" + name +
", age=" + age +
'}';
}
}
package com.fanxing.o;
import com.fanxing.Order;
import java.util.Iterator;
import java.util.List;
public class test {
//调用泛型方法
public void test1(){
System.out.println("调用泛型方法");
Order<String> r=new Order<>();
Integer[] a=new Integer[]{123,446,759};
List<Integer> copy = r.copy(a);
copy.add(12);
Iterator iterator=copy.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
public static void main(String[] args) {
Person t=new Person("sfds",15);
System.out.println(t);
Person<String> t1=new Person<String>("string","123");
System.out.println(t1);
t1.setName("sfhh");
System.out.println(t1);
/*P1 p=new P1();
p.test("张三");*/
//泛型普通方法
P1<Integer> p1=new P1<>();
p1.test(52);
test t2=new test();
t2.test1();
}
}
对比:
package com.fanxing;
public class SubOrder extends Order<Integer> {
}
package com.fanxing;
public class SubOrder1<t> extends Order<t>{//SubOrder是泛型类
}
知识点的应用
package com.fanxing;
import java.awt.*;
import java.util.*;
/*
在集合中使用泛型的要点:
1.集合接口或集合类在jdk5.0时都修改为带泛型的结构
2.在实例化集合类时,可以指明具体的泛型类型
3.指名完以后,在集合类或接口中凡是定义类或接口时,内部结构使用到类的泛型的位置,都指定为实例化的泛型类型
4.为什么使用泛型时必须是Integer,因为泛型是个类型,不能使用基本数据类型,要是用它的包装类
如果实例化时,没有指明泛型的类型,默认为Object
*/
public class test1 {
public void test1(){
//集合使用泛型之前的情况
ArrayList list = new ArrayList();
list.add(78);
list.add(88);
list.add(98);
list.add(80);
list.add(79);
//问题1,类型不安全
//list.add("Tom");//可能会放入非成绩的类型
for (Object obj:list){
//问题2.强转时会出现ClassCastException
int stuScore=(int) obj;
System.out.println(stuScore);
}
}
//集合使用泛型的情况
public void test2(){
//只能使用Integer类型的数据,在编译时就会进行类型检查,保证数据的安全
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(18);
list.add(88);
list.add(98);
list.add(80);
list.add(79);
Iterator<Integer> iterator=list.iterator();
while (iterator.hasNext()){
int study= iterator.next();
System.out.println(study);
}
/*for (Integer inte:list){
System.out.println(inte);
}*/
}
//集合使用泛型的情况,HashMap为例
public void test3(){
Map<String ,Integer> map=new HashMap<String ,Integer>();
map.put("Tom",15);
map.put("ad",13);
map.put("top",25);
Set<Map.Entry<String,Integer>> set= map.entrySet();
Iterator<Map.Entry<String, Integer>> iterator = set.iterator();
while (iterator.hasNext()){
Map.Entry<String,Integer> e= iterator.next();
String k=e.getKey();
int v=e.getValue();
System.out.println(k+"----->"+v);
}
}
public static void main(String[] args) {
test1 t=new test1();
t.test1();
System.out.println("-------------------------------");
t.test2();
System.out.println("-------------------------------");
t.test3();
}
}
package com.fanxing;
import java.util.ArrayList;
import java.util.List;
//如何自定义泛型结构:泛型类,泛型接口,泛型方法
public class Order<T> {
String name;
int id;
//类的内部结构就可以使用类的泛型
T OrderT;//T类型的变量,名字叫 OrderT,可以把T想象为int,String之类的一个‘类’
public Order(){
}
public Order(String name, int id, T orderT) {
this.name = name;
this.id = id;
this.OrderT = orderT;
}
public T getOrderT() { return OrderT; }
public void setOrderT(T orderT) { this.OrderT = orderT; }
@Override
public String toString() {
return "Order{" +
"OrderT=" + OrderT +
'}';
}
/*public void test2(){
System.out.println(orderT);
}*/
//泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
public <E> List<E> copy(E[] arr){//这里的E与上边Oread<T>无关
ArrayList<E> list=new ArrayList<>();
for (E e:arr){
list.add(e);
}
return list;
}
}
package com.fanxing;
import java.util.List;
//使用自定义的泛型结构
public class Order_test {
public void test1(){
//如果定义了泛型类,实例化时没有指明泛型,则认为泛型类型为Object类型
//要求:如果定义了类是带泛型的,建议在实例化时指明泛型
/*不建议这样
泛型不同的引用,不能相互赋值
如果泛型结构是一个接口或抽象类,则不可创建泛型类对象
静态方法中不能使用类的泛型,因为类的泛型是在实例化的时候创建的,而静态方法的创建比他早
异常类不能声明为泛型
Order o=new Order();
o.setOrderT(123);
o.setOrderT("ABC");*/
//建议这样写
Order<String> o=new Order<String>("da",51,"852456");
//o.setOrderT(123);
//o.setOrderT("ABC");
System.out.println(o);
System.out.println(o.name);
System.out.println(o.id);
}
public void test2(){
SubOrder s=new SubOrder();//因为SubOrder继承了Order
//子类在继承带泛型的父类时,指明了泛型,不再需要指明泛型
s.setOrderT(15315);
}
public void test3(){
SubOrder1<String> s=new SubOrder1();
s.setOrderT("assd");
}
//测试泛型方法
public void test4(){
Order<String> o=new Order<>();
Integer[] a=new Integer[]{1,2,3,4};
List<Integer> list= o.copy(a);
}
public static void main(String[] args) {
Order_test t=new Order_test();
t.test1();
}
}
class Father<T1,T2>{
}
//1.子类不保留父类的泛型
//1).没有类型,擦除
class one extends Father{
}
//2).具体类型
class two extends Father<Integer,String>{
}
//2.子类保留父类的泛型
//1).全部保留
class three<T1,T2,A,B> extends Father<T1,T2>{
}
//2).部分保留
class four<T2> extends Father<String,T2>{}
泛型通配符
package com.fanxing;
import com.fanxing.tpf.Animal;
import com.fanxing.tpf.Cat;
import com.fanxing.tpf.miniCat;
import org.omg.CORBA.Object;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
*1. 泛型在继承方面的体现
* 类A是类B的父类 G<A>和G<B>不具备父子关系,二者是平级的
* 类A是类B的父类 A<G>的B<G>父类
*
* */
public class jc_tx {
//泛型在继承方面的体现
public void test1(){
Object obj=null;
String str=null;
obj=str;
Object[] o=new Object[10];
String[] s=new String[10];
o=s;
List<Object> list1=null;
List<String> list2=null;
show1(list1);
show2(list2);
List<String> l1=null;
ArrayList<String> l2=null;
l1=l2;
//list1=list2 等价于 Date date=new Date() str=date
}
public void show1(List<Object> list){
}
public void show2(List<String> list){
}
/*
2. 通配符的使用
* 通配符 ?
类A是类B的父类 G<A>和G<B>不具备父子关系,二者共同的父类是:G<?>
* */
public void test3(){
List<Object> list1=null;
List<String> list2=null;
List<?> list4=new ArrayList<String>();
//list4.add
list1.add(1235);
list1.add(351531);*//*
List<?> list =null;
list=list1;
list=list2;
test4(list);*//*
List<String> list3=new ArrayList<>();
list3.add("aa");
list3.add("bb");
list3.add("cc");
list=list3;//相当于list也指向了ArrayList()
//list.add(null);//只能加null
//获取(读取)
Object o = list.get(1);
System.out.println(o);
}
public void test4(List<?> list){
Iterator<?> iterator=list.iterator();
while (iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
}
/*
* 3.有限制条件的通配符使用
* ? entends Person
* ? super Person
*
* Student继承了Person
* //<? extends A> == (-无穷,A] 即:A或者其子类型
//<? super A> ==[A,+无穷) 即:A或者其父类
*
* ? extends add()受限
* ?super get()受限
*
* 想要读 用extends 想要写用super
*/
public static void test4(ArrayList<? extends Cat> list){//上限通配符
//使用类型通配符上限就不能再添加元素
//使用类型通配符下限就能再添加元素,但不保证元素类型的约束要求
for (int i = 0; i <list.size() ; i++) {
Cat cat=list.get(i);
System.out.println(cat);
}
}
//Animal 是Catd 父类,Cat是miniCat父类:
public static void test5(ArrayList<? super Cat> lists){//下限通配符
for (int i = 0; i <lists.size() ; i++) {
Object cat=lists.get(i);
System.out.println(cat);
}
}
public void test6(){
//List<Animal> l1=new ArrayList<>();
List<? extends Cat> l1=null;
List<? super Cat> l2=null;
//List<miniCat> l3=new ArrayList<>();
List<Animal> l3=new ArrayList<>();
List<Cat> l4=new ArrayList<>();
List<miniCat> l5=new ArrayList<>();
//读数据
l1=l4;
//l1=l5;
//l1=l3;
Animal cats= l1.get(0);
l2=l3;
l2=l4;
//l2=l5;
java.lang.Object obj = l2.get(0);
//写数据
l1=l4;
boolean add1 = l1.add(null);
l2=l4;
l2.add(miniCat);
}
public static void main(String[] args) {
jc_tx j=new jc_tx();
//j.test3();
ArrayList<Animal> animals=new ArrayList<>();
ArrayList<Cat> cats=new ArrayList<>();
ArrayList<miniCat> miniCats=new ArrayList<miniCat>();
//进行调用
//test4(animals);无法调用
test4(cats);
test4(miniCats);
cats.addAll(cats);
cats.addAll(miniCats);
}
}
package com.fanxing.exer1;
import java.util.*;
public class DAO<T> {
private Map<String ,T> map = new HashMap<String, T>();
//保存T类型的对象到Map成员变量中
public void save(String id,T entity){
map.put(id,entity);
}
//从map中获取id对应的对象
public void get(String id){
T t = map.get(id);
}
//替换map中key为的id内容,改为entity对象
public void update(String id,T entity){
if(map.containsKey(id)){
map.put(id,entity);
}
}
//返回map中存放的所有T对象
public List<T> list(){
List<T> list=new ArrayList<>();//先建立一个list
Collection<T> values = map.values();
for(T t:values){
list.add(t);
}
return list;
}
public void delete(String id){
map.remove(id);
}
}
package com.fanxing.exer1;
public class User {
private int id;
private int age;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
public User(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public User() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (id != user.id) return false;
if (age != user.age) return false;
return name != null ? name.equals(user.name) : user.name == null;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + age;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
package com.fanxing.exer1;
import java.util.Iterator;
import java.util.List;
/*
*
* 创建DAO类的对象,分别调用 save,get update list delete方法来操作User对象*/
public class DAOTest {
public static void main(String[] args) {
DAO<User> dao=new DAO<>();
dao.save("1001",new User(1001,30,"zjl"));
dao.save("1002",new User(1002,35,"zgr"));
dao.save("1003",new User(1003,38,"zxy"));
dao.update("1003",new User(1003,40,"myf"));
dao.delete("1002");
List<User> list = dao.list();
Iterator<User> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}