• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
keaiduojava
博客园    首页    新随笔    联系   管理    订阅  订阅
泛型

泛型

使用传统方法分析:

  1. 不能对加入到集合ArrayList中的数据类型进行约束(不安全)
  2. 遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响

泛型的好处:

  1. 编译时,检查添加元素的类型。提高了安全性
  2. 减少了类型转换的次数,提高效率

不使用泛型

Dog->Object->Dog//放入到ArrayList会先转成Object,在取出时还需要转换成Dog

使用泛型

Dog->Dog->Dog//放入时和取出时不需要类型转换,提高效率

/*
1.请编写程序,在 ArrayList 中,添加 3 个 Dog 对象
2.Dog 对象含有 name 和 age, 并输出 name 和 age (要求使用 getXxx())
3.使用泛型来完成代码
*/
public class Generic02 {
    public static void main(String[] args) {
        //ArrayList<Dog>表示存放到ArrayList集合中的元素是Dog类型
        //如果编译器发现添加的类型不满足要求,就会报错
        //在遍历的时候,可以直接取出 Dog 类型而不是 Object
        //public class ArrayList<E> {};把E称为泛型,那么Dog->E
        ArrayList<Dog> arrayList = new ArrayList<Dog>();
        arrayList.add(new Dog("旺财", 10));
        arrayList.add(new Dog("发财", 1));
        arrayList.add(new Dog("小黄", 5));
        //arrayList.add(new Cat("招财猫", 8));报错

        for(Dog dog:arrayList){
            System.out.println(dog.getName()+"="+dog.getAge());
        }
    }
}


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 { //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;
    }
}

泛(广泛)型(类型)=>Integer,String,Dog

泛型又称参数化类型,是JDK5.0出现的新特性,解决数据类型的安全性问题

在类声明或实例化时只需要指定好需要的具体类型即可。

Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮

泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值类型,或者是参数类型。

public class Generic03 {
    public static void main(String[] args) {
        Person<String> stringPerson = new Person<String>("北京你好");
        stringPerson.show();//class java.lang.String
        //Person类:E可以被赋予任何数据类型,需要S是什么数据类型就设置什么数据类型,此处为String
        Person<Integer> person2 = new Person<Integer> (100);
        person2.show();//lass java.lang.Integer
    }
}

class Person<E>{
    E s;//E表示s的数据类型,该数据类型是在定义Person对象时指定,即在编译期间就确定E是什么类型

    public Person(E s) {//E也可以是参数类型
        this.s = s;
    }
    public E f(){//返回类型使用E
        return s;
    }

    public void show() {
        System.out.println(s.getClass());//显示 s 的运行类型
    }

}

泛型语法

泛型的声明:

interface 接口{}和class类<K,V>{}

/比如:List,ArrayList

说明:其中T,K,V不代表值,而是表示类型;

​ 任意字母都可以。常用T表示,是Type的缩写

泛型的实例化:

要在类名后面指定类型参数的值。如:

List strList = new ArrayList();

Iterator iterator = customer.iterator();

public class GenericExercise {
    public static void main(String[] args) {
        //使用泛型方式给HashSet放入3个学生对象
        HashSet<Student> students = new HashSet<Student> ();
        students.add(new Student("jack",18));
        students.add(new Student("tom",28));
        students.add(new Student("mary",19));

        //遍历
        for(Student student:students){
            System.out.println(student);
        }
        
        //使用泛型给HashMap放入三个学生对象
        HashMap<String,Student> hm = new HashMap<String,Student>();
        /*
            public class HashMap<K,V> {}
        */
        hm.put("milan",new Student("milan",38));
        hm.put("smith",new Student("smith",48));
        hm.put("amy",new Student("amy",20));
        
        //迭代器EntrySet
        Set<Map.Entry<String, Student>> entries = hm.entrySet();
        /*
            public Set<Map.Entry<K,V>> entrySet() {
                Set<Map.Entry<K,V>> es;
                return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
            }
        */
        Iterator<Map.Entry<String, Student>> iterator = entries.iterator();
        /*
            public final Iterator<Map.Entry<K,V>> iterator() {
                return new EntryIterator();
            }
         */
        while(iterator.hasNext()){
            Map.Entry<String, Student> next = iterator.next();
            System.out.println(next.getKey() + "===>" + next.getValue());
        }
    }
}

class Student{
    private String name;
    private int age;

    public Student(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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

泛型使用的注意事项和细节

  1. interface List{},public class HashSet{}等等

​ 说明:T,E只能是引用类型,不能说基本数据类型

​ Listlist = new ArrayList();//正确

​ Listlist2 = new ArrayList();//错误,int是基本数据类型

  1. 在指定泛型具体类型后,可以传入该类型或者其子类类型
  2. 泛型使用形式

​ Listlist1 = new ArrayList();

​ Listlist2 = new ArrayList<>();//编译器会进行类型推断

  1. 如果我们这样写ArrayList list3 = new ArrayList();默认给它的泛型是[ E就是Object],等价于ArrayList
posted on 2023-02-28 21:48  ·草莓味的可爱多  阅读(6)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3