Java 泛型学习——————
泛型的好处
1.编译时,检查添加元素的类型,提高了安全性
2.减少了类型转换的次数,提高了效率
实例如下:不使用泛型Dog->加入->Object->取出->Dog//放入到ArrayList会转到Object,取出还需要转到Dog
import java.util.ArrayList;
public 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{
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;
}
}
class Generic{
public static void main(String[] args) {
ArrayList list= new ArrayList();
list.add(new Dog("旺财",12));
list.add(new Dog("发财",1));
list.add(new Dog("小黄",13));
//增加一只猫,这里编译时不会报错,但运行会报错
list.add(new Cat("招财猫",23));
//增强for循环
for(Object o:list){
//向下转型Object--》Dog
Dog dog=(Dog)o;
System.out.println(dog.getName()+"-"+dog.getAge());
}
}
}
使用了泛型
Dog->Dog->Dog,放进去和取出时都不需要类型转换
实例如下,我们修改 Genreic类代码
、、、、、、、这上面还是Cat和Dog类不变
public class Genreic {
public static void main(String[] args) {
ArrayList<Dog> list=new ArrayList<Dog>();
list.add(new Dog("招财狗",23));
list.add(new Dog("财狗",25));
// 泛型约束,编译器检测,不满足要求会报错
// list.add(new Cat("猫",23));
//便利时可以直接取出Dog类型,而不是Object类型,不用向下转型
for (Dog o:list){
System.out.println(o.getName()+"-"+o.getAge());
}
}
}
泛型介绍
泛型又称参数化类型,(泛型可以理解为一种可以表示数据类型的一种数据类型),是jdk5.0出现的新特性,解决数据类型安全的问题
注意1 泛型指向的数据类型要求是引用数据类型而不是基本数据类型
ArrayList<Integer> list1=new ArrayList<Integer>();
// ArrayList<int> list2=new ArrayList<int>();
注意二:在给泛型指定具体类型后,可以给类型出入它或者他的子类类型
public class Test {
pig<A>pig=new pig<A>(new A());
//在给泛型指定具体类型后,可以给类型传入它或者他的子类类型
pig<A>pig2=new pig<A>(new B());
}
class A{};
class B extends A{};
class pig<E>{
E e;
public pig(E e) {
this.e = e;
}
}
注意三:如果没有给泛型指定数据类型,编译器默认是Object
//如果这样写,默认泛型是Object,两者等价
ArrayList list=new ArrayList();
ArrayList<Object>list2=new ArrayList<>();
实战题目
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
class Eployee {
private String name;
private int sal;
private Mydata birthdy;
public Eployee() {
}
public Eployee(String name, int sal, Mydata birthdy) {
this.name = name;
this.sal = sal;
this.birthdy = birthdy;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSal() {
return sal;
}
public void setSal(int sal) {
this.sal = sal;
}
public Mydata getBirthdy() {
return birthdy;
}
public void setBirthdy(Mydata birthdy) {
this.birthdy = birthdy;
}
@Override
public String toString() {
return "\nEployee{" +
"name='" + name + '\'' +
", sal=" + sal +
", birthdy=" + birthdy +
'}';
}
}
class Mydata implements Comparable<Mydata>{
private int month;
private int year;
private int day;
public Mydata() {
}
public Mydata(int year, int month, int day) {
this.month = month;
this.year = year;
this.day = day;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
@Override
public String toString() {
return "Mydata{" +
"month=" + month +
", year=" + year +
", day=" + day +
'}';
}
@Override
public int compareTo(Mydata o) {
int yearminth=year- o.getYear();
if (yearminth!=0){
return yearminth;
}
//比较minth
int monthminth=month-o.getMonth();
if (monthminth!=0) {
return monthminth;
}
return day-o.getDay();
}
}
class Test{
public static void main(String[] args) {
ArrayList<Eployee>list=new ArrayList<>();
list.add(new Eployee("tom",30000,new Mydata(2000,11,27)));;
list.add(new Eployee("jact",12000,new Mydata(2001,12,12)));;
list.add(new Eployee("tom",60000,new Mydata(2000,10,27)));;
System.out.println("eplyees"+list);
System.out.println("-----------------排序后------------------");
list.sort(new Comparator<Eployee>() {
@Override
public int compare(Eployee o1, Eployee o2) {
//先对传入的实参进行验证
if (!(o1 instanceof Eployee && o2 instanceof Eployee)) {
System.out.println("类型不匹配");
return 0;
}
//如果类型相同,就比较姓名
int i = o1.getName().compareTo(o2.getName());
if (i != 0) {
return i;
}
//比较生日
return o1.getBirthdy().compareTo(o2.getBirthdy());
}
});
System.out.println(list);
}
}
自定义泛型
基本语法
class 类名<T,R..>{//可以有多个
成员.......
}
普通成员可以使用泛型
使用泛型的数组不能初始化
class Targer<T,R,M>{
String name;
T t;
R r;
M m;
//因为数组在new 不能确定R数据类型,无法知道开辟多大空间
// R[]rs =new R[8];
//但是可以定义
R[]rs2;
}
静态方法中不能使用类的泛型
class Targer<T,R,M>{
String name;
T t;
R r;
M m;
//因为静态和类相关,在类加载的时候对象还没有创建
//如果静态方法和属性使用了泛型,JVM无法完成初始化
static T t;
public Static void m1 (T t){
}
}
自定义泛型接口
基本语法
在接口中静态成员也不能使用泛型
泛型接口的类型,在继承接口或者实现接口实现
interface 接口名<T,R..>{ }
package com.taoge.con;
interface Test2<U,R> {
int n=10;
//在接口中属性也是静态属性
// U name; 错误
//普通方法也可以使用接口泛型
R get(U u );
void hi(U u,R r);
//在jdk8中,可以在接口中使用默认方法,也可以使用泛型
default R meth(U u){
return null;
}
}
//在继承接口时实现接口的类型
interface Test3 extends Test2<String,Double>{}
//但我们实现Test3接口时,因为在Test2中指定了U为String,R为Double
//在实现方法时,自动替代
class person implements Test3{
@Override
public Double get(String s) {
return null;
}
@Override
public void hi(String s, Double aDouble) {
}
}
自定义泛型方法
基本语法
修饰符<T,R..>返回类型 方法名(形参列表){
}
泛型方法可以定义在普通类中也可以定义在泛型类中
注意 反正泛型方法带个<T,R..>这个东西
public void eat(T t){}//这个不是泛型方法,只是使用了泛型
public <T,R> void eat(T t,R r){}//这个是
泛型的继承和通配符
泛型不具备继承性
package com.taoge.con;
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import java.util.ArrayList;
public class Test {
//可以多态
Object o=new String("xx");
//错误
// ArrayList<Object>list=new ArrayList<String>();
}
通配符
起到一种约束的作用
<?>:支持任意泛型类型
<? extends A>支出A类以及A的子类,规定了泛型的上限
<? super A>:支持A类及父类,不限于直接父类,规定了泛型下限
实战
package com.taoge.con;
import java.security.Key;
import java.util.*;
public class DAO<T> {
private Map<String,T> map=new HashMap<>();
//从map中获取id对象
public T get(String id){
return map.get(id);
}
//替代
public void update(String id,T entity){
map.put(id,entity);
}
//返回map存放的T对象
public List<T> lsit(){
//创建ArrList
ArrayList<T> list = new ArrayList<>();
//便利Map
Set<String> keyset = map.keySet();
for (String key:keyset){
list.add(map.get(key));
}
return list;
}
//删除
public void delete(String id){
map.remove(id);
}
//保存
public void sava(String id,T entity){
map.put(id,entity);
}
}
class Uesr{
private int id;
private int age;
private String name;
public Uesr(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = 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;
}
}
//测试
class Test{
public static void main(String[] args) {
}
}
@Test
public void testlist(){
DAO<Uesr>dao=new DAO<>();
dao.sava("111",new Uesr(1,19,"jack"));
dao.sava("222",new Uesr(2,12,"wewe"));
List<Uesr>list= dao.lsit();
System.out.println("list"+list);
//剩下不测了
}