栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Day016--java中的泛型机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Day016--java中的泛型机制

 JDK1.5版本中提供了泛型的概念。泛型实际上就是使程序员定义安全的类型。在没有出现泛型时,java提供来了对Object的引用“任意化”操作(对Object引用进行“向上/下转型操作”)

案例1

现在我们创建一个集合a并将两只猫咪放入集合中,并使用向下转型,得到猫咪对象,打印输出猫咪的名字和年龄。

在上面的案例中我们传入的是猫咪对象,向下转型的类型也是猫咪类。但是有些时候我们也会不小心将其他的类型加入集合中,并将其向下转型成猫咪类。这个时候编译器是不会有报错的,但是在运行时就会报ClassCastException异常错误。如下,我们创建一个Dog类,并将其加入集合a中。

代码:

import java.util.ArrayList;
public class WithoutG {
public static void main(String[] args) {
	ArrayList a=new ArrayList();  
    a.add(new Cat("咪咪",3));     
    a.add(new Cat("喵喵",4));
    a.add(new Dog("哈士奇",4));     //在这里我们加入了Dog对象
    for(Object o:a) {
    	Cat c=(Cat)o;
    	System.out.println(c.name+"(>^ω^<)"+c.age+"岁了");
    }
}}
class Cat{
	 String name;
	 int age;
	 public Cat(String name,int age) {
		 this.name=name;
		 this.age=age;
	 }
	@Override
	public String toString() {   //重写Cat类的toString方法
		return "Cat [name=" + name + ", age=" + age + "]";
	}
	 
}
class Dog{
	 String name;
	 int age;
	 public Dog(String name,int age) {
		 this.name=name;
		 this.age=age;
	 }
	@Override
	public String toString() {  //重写Dog类的toString方法
		return "Dog [name=" + name + ", age=" + age + "]";
	}}
	 
案例2

我们可以看到哦上面的(Object的强制类型转换一般是“向下转型”容易出现问题)存在安全隐患,所以在java中提供泛型机制。我们可以在类名后面加上-----T是type的缩写。表示我们的类是一个泛型类,同时该类返回和接收的参数使用了T这个类型。现在我们将上面的案例进行修改:

进行如上修改后编译器就会在运行前进行检查类型匹配是否正确,这样子就不会一不小心传入不同的对象了如果想要猫狗放一个集合里面的话,我们可以创建一个ArrayList的泛型类,如下: 

我们将集合修改成泛型类这样子可以传入两个不同类的对象,就不会出现“向下转型”异常的错误。

import java.util.*;
public class Gennic{
	private T t;    //创建T类型(泛型类型)的变量。
	public T getT() {    //得到变量的值
		return t;
	}
	public void setT(T t) {   //设置变量的值
		this.t = t;
	}

	@Override
	public String toString() {
		return "Gennic [t=" + t + "]";
	}
	public static void main(String[] args) {
	Gennic arrayList=new Gennic();    //创建泛型对象
	 //-----------------这里不变-----------------
	ArrayList a=new ArrayList();  
    a.add(new Cat("咪咪",3));     
    a.add(new Cat("喵喵",4));
    a.add(new Dog("哈士奇",4));
    //-----------------这里不变-----------------
    arrayList.setT(a);           //将我们的集合作为参数传入arrayList中(a变泛型类)
    for(Object t:arrayList.getT()) {      //因为我们传入的不是一个类型,因此我们使用Object(所有子类的超类)来进行接收
    	System.out.println(t.toString());   
    }
   
//    for(Object o:a) {    //将集合a传入Object超类中
//    	Cat c=(Cat) o;   //使用向下转型,将Object类型转换成Cat类型
//    	System.out.println(c.name+"  is      "+c.age+"   years old");
//    }
	}

}
class Cat{
	 String name;
	 int age;
	 public Cat(String name,int age) {
		 this.name=name;
		 this.age=age;
	 }
	@Override
	public String toString() {   //重写Cat类的toString方法
		return "Cat [name=" + name + ", age=" + age + "]";
	}
	 
}
class Dog{
	 String name;
	 int age;
	 public Dog(String name,int age) {
		 this.name=name;
		 this.age=age;
	 }
	@Override
	public String toString() {  //重写Dog类的toString方法
		return "Dog [name=" + name + ", age=" + age + "]";
	}
	 
}

我们在定义泛型类时,也可以声明多个类型。形如:泛型类名称

  • T1,T2:都是可能被定义的类型

例如:泛型类名  对象名=new 泛型类名 ();

案例3

这种案例一般出现在map集合中,如hashMap及treeMap,下面我们来使用hashMap创建一个集合,用来存储员工类(键为员工的名字,值为员工的信息)--涉及的集合请跳转到Day012进行阅读

 代码:

import java.util.*;
import java.util.Map.Entry;

public class WithG {
	//使用HashMap创建一个集合,用来存储员工类(键为员工的名字,值为员工的信息)
	//最后以“张三的信息为张三,wage=1800,age=30”输出打印集合中的键和值
	public static void main(String[] args) {
		Map map=new HashMap();  //设置两个类型
		Employee e1=new Employee("张三",18000,30);
		Employee e2=new Employee("李四",1800,30);
		Employee e3=new Employee("王五",28000,30);
		map.put(e1.name,e1 );
		map.put(e2.name,e2 );
		map.put(e3.name,e3 );
		Set set=map.entrySet();
		Iterator it=set.iterator();
		while(it.hasNext()) {
			Map.Entry entry=(Entry) it.next();
			System.out.println(entry.getKey()+"的信息为"+entry.getValue());
		}
		}
	}
class Employee{
	String name;
	int wage;
	int age;
	public Employee(String name,int wage,int age) {
		this.name=name;
		this.wage=wage;
		this.age=age;
	}
	@Override
	public String toString() {
		return  name + ", wage=" + wage + ", age=" + age ;
	}
	
}
案例4

//定义Employee类,该类包含private成员变量name,sal,birthday(为MyDate类的对象)

//为每一个属性定义getter和setter方法,重写toString方法输出三个变量信息

//MyDate类包含private成员变量,month,day,year,并为每一个属性定义getter和setter方法
//创建员工类的3个对象,并把这些对象放入ArrayList集合中(ArrayList需要使用泛型来定义)
//对集合中的元素进行排序(调用sort方法,传入Comparator对象,先按照name排序,如果name相同,则按照生日日期的先后排序),并遍历输出

年月日时MyDate里面的属性,每当我们要去使用这三个属性时,就需要去调用getBirthday方法得到,太过于麻烦了,如下所示:

 因此我们可以将它简化一下,将这些方法放入MyDate类中,并让MyDate类去实现Comparator接口,这样子就可以使用比较器并重写comparTo方法。

 代码:

import java.util.*;
import java.lang.*;
@SuppressWarnings({"all"})
public class Case2 {
	public static void main(String[] args) {

    Employee1 e1=new Employee1("Amy",3000,new MyDate(2000,12,2));
    Employee1 e2=new Employee1("Mike",20000,new MyDate(2002,2,4));
    Employee1 e3=new Employee1("Mike",35000,new MyDate(1998,3,5));
    ArrayList arrayList=new ArrayList<>();
    arrayList.add(e1);
    arrayList.add(e2);
    arrayList.add(e3);
    System.out.println(arrayList);
	arrayList.sort(new Comparator() {   //使用ArrayList集合自带的sort方法,之后我们重写比较器
		public int compare(Employee1 e1,Employee1 e2) {    //覆盖原有的compare方法,传入两个员工类对象
			int objName=e1.getName().compareTo(e2.getName());   //比较对象的名字使用compaTo方法,如果相同,返回0,不同则不是0
			if(objName!=0) {
				return objName;
		}
			return e1.getBirthday().compareTo(e2.getBirthday());     //直接调用员工类中的getBirthday方法即可
		}	
		});
	System.out.println("=============泛型类比较=======");
	System.out.println(arrayList);        //打印比较后的集合容器
	}}
class Employee1{
   private	String name;
   private  double sal;
   private MyDate birthday;
   
public String toString() {
	return "nEmployee [name=" + name + ", sal=" + sal + ", month=" + birthday + "]";
}
public Employee1() {}    
public Employee1(String name, double sal, MyDate birthday) {
	this.name = name;
	this.sal = sal;
	this.birthday = birthday;
}
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public double getSal() {
	return sal;
}
public void setSal(double sal) {
	this.sal = sal;
}
public MyDate getMonth() {
	return birthday;
}
public void setMonth(MyDate month) {
	this.birthday = birthday;
}
public MyDate getBirthday() {
	return birthday;
}
public void setBirthday(MyDate birthday) {
	this.birthday = birthday;
}

   
}
class MyDate  implements Comparable{     //创建MyDate类,实现Comparable接口,将该类作为参数传入
	private int year;
	private int month;
	private int day;
	public MyDate() {}
	@Override
	public int compareTo(MyDate date) {           //覆盖重写compareTo方法,传入的依旧是当前类
		int dateYear=year-date.year;   //如果name相同,我们再比较出生年份,并将结果返回
		if(dateYear!=0) {    
			return dateYear;
		}
		int dateMonth=month-date.month;   //如果年份相同,我们再比较出生月份,并将结果返回
		if(dateMonth!=0) {
			return dateMonth;
		}
		return 	day-date.day;    //如果月份相同,那么我们就直接返回两个的相减值

		
	}
	public MyDate(int year, int month, int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		this.month = month;
	}
	public int getDay() {
		return day;
	}
	public void setDay(int day) {
		this.day = day;
	}
	@Override
	public String toString() {
		return "MyDate [year=" + year + ", month=" + month + ", day=" + day + "]";
	}	
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/876840.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号