IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java面向对象之泛型 -> 正文阅读

[Java知识库]Java面向对象之泛型

1、泛型

1.1、需求引出

在这里插入图片描述

package generic;

import java.util.ArrayList;

@SuppressWarnings({"all"})
public class Generic01 {
    public static void main(String[] args) {
        // 使用传统的方法来解决
        ArrayList arrayList = new ArrayList();
        arrayList.add(new Dog("旺财", 10));
        arrayList.add(new Dog("发财", 1));
        arrayList.add(new Dog("小黄", 5));

        // 假如我们不小心, 添加了一只猫
        arrayList.add(new Cat("招财猫", 8));

        // 遍历
        for (Object o : arrayList) {
            // 向下转型 Object -> Dog
            Dog dog = (Dog) o;
            System.out.println(dog.getName() + " - " + dog.getAge());
            /**
             * 旺财 - 10
             * 发财 - 1
             * 小黄 - 5
             * Exception in thread "main" java.lang.ClassCastException: generic.Cat cannot be cast to generic.Dog
             * 	at generic.Generic01.main(Generic01.java:20)
             * 	由于里面混入了猫类, 在向下转型的时候报错了
             */
        }

    }
}

/**
 * 请编写程序, 在 ArrayList 中, 添加 3 个 Dog 对象
 * Dog 对象含有 name 和 age, 并输出 name 和 age (要求使用 getXxx())
 */
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;
    }
}

1.2、使用传统方法的问题分析

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

1.3、用泛型来解决前面的问题

ArrayList arrayList = new ArrayList();

package generic;

import java.util.ArrayList;

@SuppressWarnings({"all"})
public class Generic01 {
    public static void main(String[] args) {
        // 1. 当我们 ArrayList<Dog> 表示存放到 ArrayList 集合中的元素是 Dog 类型
        // 2. 如果编译器发现添加的类型, 不满足要求, 就会报错
        // 3. 在遍历的时候, 可以直接取出 Dog 类型而不是 Object
        // 4. 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());
            /**
             * 旺财 - 10
             * 发财 - 1
             * 小黄 - 5
             */
        }

    }
}

/**
 * 请编写程序, 在 ArrayList 中, 添加 3 个 Dog 对象
 * Dog 对象含有 name 和 age, 并输出 name 和 age (要求使用 getXxx())
 */
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;
    }
}

1.4、泛型的好处

在这里插入图片描述

1.5、泛型介绍

在这里插入图片描述
在这里插入图片描述

package generic;

public class Generic03 {
    public static void main(String[] args) {
        // 注意, 特别强调: E 具体的数据类型在定义 Person 对象的时候指定, 即在编译期间, 就确定 E 是什么类型
        Person<String> person = new Person<String>("hello");
        person.show();  // class java.lang.String
        /**
         * 可以这样理解上面的 Person 类
         * class Person {
         *     String s;  // E 表示 s 的数据类型, 该数据类型在定义 Person 对象的时候指定, 即在编译期间, 就确定 E 是什么类型
         *
         *     public Person(String s) {  // E 也可以是参数类型
         *         this.s = s;
         *     }
         *
         *     public String f() {  // 返回类型使用
         *         return s;
         *     }
         *
         *     public void show() {
         *         System.out.println(s.getClass());  // 显示 s 的运行类型
         *     }
         * }
         */

        Person<Integer> person2 = new Person<>(100);
        person2.show();  // class java.lang.Integer
        /**
         * class Person {
         *     Integer s;  // E 表示 s 的数据类型, 该数据类型在定义 Person 对象的时候指定, 即在编译期间, 就确定 E 是什么类型
         *
         *     public Person(Integer s) {  // E 也可以是参数类型
         *         this.s = s;
         *     }
         *
         *     public Integer f() {  // 返回类型使用
         *         return s;
         *     }
         *
         *     public void show() {
         *         System.out.println(s.getClass());  // 显示 s 的运行类型
         *     }
         * }
         */
    }
}

// 泛型的作用是: 可以在类声明时通过一个标识表示类中某个属性的类型
// 或者是某个方法的返回值的类型, 或者是参数类型
class Person<E> {
    E s;  // E 表示 s 的数据类型, 该数据类型在定义 Person 对象的时候指定, 即在编译期间, 就确定 E 是什么类型

    public Person(E s) {  // E 也可以是参数类型
        this.s = s;
    }

    public E f() {  // 返回类型使用
        return s;
    }

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

1.6、泛型的语法

1.6.1、泛型的声明

在这里插入图片描述

1.6.2、泛型的实例化

在这里插入图片描述

1.6.3、泛型使用举例

在这里插入图片描述

package generic;

import java.util.*;

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);
            /**
             * Student{name='mary', age=19}
             * Student{name='tom', age=28}
             * Student{name='jack', age=18}
             */
        }

        // 使用泛型方式给 HashMap 放入 3 个学生对象
        // K -> String V -> Student
        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("jack", new Student("jack", 15));

        // 迭代器 EntrySet
        /*
        public Set<Map.Entry<K,V>> entrySet() {
            Set<Map.Entry<K,V>> es;
            return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
        }
         */
        Set<Map.Entry<String, Student>> entries = hm.entrySet();
        /*
        public final Iterator<Map.Entry<K,V>> iterator() {
            return new EntryIterator();
        }
         */
        Iterator<Map.Entry<String, Student>> iterator = entries.iterator();
        System.out.println("==============================");
        while (iterator.hasNext()) {
            Map.Entry<String, Student> next = iterator.next();
            System.out.println(next.getKey() + "-" + next.getValue());
        }
        /**
         * ==============================
         * smith-Student{name='smith', age=48}
         * milan-Student{name='milan', age=38}
         * jack-Student{name='jack', age=15}
         */
    }
}

/**
 * 创建 3 个学生对象
 * 放入到 HashSet 中学生对象, 使用
 * 放入到 HashMap 中, 要求 Key 是 String name, Value 就是 学生对象
 * 使用两种方式遍历
 */
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 +
                '}';
    }
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-23 15:37:37  更:2021-12-23 15:39:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:56:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码