java泛型学习篇(一)

java泛型学习篇(一)

1 学习泛型前的传统思路

1.1 遍历集合中元素的方法

1.1.1 思路
①用foreach进行遍历
②把每个Object对象强转成所需类型
③打印其值
1.1.2 示例代码
import java.util.ArrayList;
public class Generic01 {
    public static void main(String[] args) {
        long startTime=System.currentTimeMillis();
        ArrayList  arr= new ArrayList<>();
        for (int i = 0; i <100000; i++) {
            arr.add(Integer.valueOf(i));
        }
        for (Object o : arr) {
            //你想要使用Integer类型的方法必须强转,每一个数据都得这样,很麻烦
            Integer temp= (Integer) o;
            System.out.println(temp.intValue());
        }
        long endTime=System.currentTimeMillis();
        System.out.println("执行时长为(单位:毫秒): "+(endTime-startTime));
    }
}

1.1.3 运行截图

在这里插入图片描述

1.2 集合中若存放了非同类型的数据,并不会出现错误,出现的是运行时异常

1.2.1 示例代码
import java.util.ArrayList;

public class Generic02 {
    public static void main(String[] args) {
        long startTime=System.currentTimeMillis();
        ArrayList  arr= new ArrayList<>();
        for (int i = 0; i <100000; i++) {
            arr.add(Integer.valueOf(i));
        }
        arr.add("123");
        for (Object o : arr) {
            //你想要使用Integer类型的方法必须强转,每一个数据都得这样,很麻烦
            Integer temp= (Integer) o;
            System.out.println(temp.intValue());
        }
        long endTime=System.currentTimeMillis();
        System.out.println("执行时长为(单位:毫秒): "+(endTime-startTime));
    }
}
1.2.2 运行截图

在这里插入图片描述

2 学习泛型后的思路

2.1 遍历集合中元素的方法

2.1.1 思路
①在集合定义的时候加上泛型约束
②使用foreach循环打印值
2.1.2 示例代码
import java.util.ArrayList;
public class Generic03 {
    public static void main(String[] args) {
        long startTime=System.currentTimeMillis();
        ArrayList<Integer>  arr= new ArrayList<>();
        for (int i = 0; i <100000; i++) {
            arr.add(Integer.valueOf(i));
        }
        for (Integer o : arr) {
            //你想要使用Integer类型的方法必须强转,每一个数据都得这样,很麻烦
            System.out.println(o.intValue());
        }
        long endTime=System.currentTimeMillis();
        System.out.println("执行时长为(单位:毫秒): "+(endTime-startTime));
    }
}
2.1.3 运行截图

在这里插入图片描述

2.2 集合中若存放了非同类型的数据,会出现错误,提示使用者必须改(不改必报错)

2.2.1 示例代码
import java.util.ArrayList;
public class Generic04 {
    public static void main(String[] args) {
        long startTime=System.currentTimeMillis();
        ArrayList<Integer>  arr= new ArrayList<>();
        for (int i = 0; i <100000; i++) {
            arr.add(Integer.valueOf(i));
        }
        arr.add("123");
        for (Integer o : arr) {
            System.out.println(o.intValue());
        }
        long endTime=System.currentTimeMillis();
        System.out.println("执行时长为(单位:毫秒): "+(endTime-startTime));
    }
}
2.2.2 运行截图
a idea给出的错误提示

在这里插入图片描述

b 点击运行后

在这里插入图片描述

3 使用泛型好处

3.1 编译时,自动检查添加元素的类型,提高安全性,不是指定的类型是加不进去的
3.2 减少了类型转换次数和花费判断是否是一个类的实例的时间,有效提高了效率

4 泛型的理解

泛型是一种广泛的类型,是一种数据类型的数据类型,可以是Integer、String等
泛型又称之为参数化类型,是JDK5.0后出现的新特性(解决了数据类型的安全性问题)
泛型可以保证在编译时没有报错,运行时一定不会出现ClassCastException异常
泛型的作用:在类声明时通过一个标识符来表示类中某个属性的类型OR 方法返回值的类型 OR 参数类型

5 泛型的语法以及练习

5.1 语法

interface 接口<T>{}和 class类<k,v>{}
//T、K、V并不代表值,而是代表类型
//其实任意字母都可以,常用T表示,是Type的缩写

5.2 练习题目

5.2.1 题目内容
①创建5个教师对象
②把教师对象放入到HashSet中,要求约束为教师对象
③把教师对象放入到HashMap中,要求key为String类型,value为教师对象类型
④对②③这两种情况进行遍历,输出对应的结果即可
5.2.2 Teacher类代码
class Teacher{
    private String name;
    private int age;

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
5.2.3 示例代码
import org.apache.poi.ss.formula.functions.T;

import java.util.*;

public class GenericPractice {
    public static void main(String[] args) {
         //A.使用HashSet
        HashSet<Teacher> set = new HashSet<Teacher>();
        set.add(new Teacher("小明", 27));
        set.add(new Teacher("小洪", 32));
        set.add(new Teacher("小亮", 22));
        //使用增强for循环进行打印
        for (Teacher o :set) {
            System.out.println(o);
        }
        System.out.println("=========使用hashMap的方式===============");
        //B 使用HashMap
        HashMap<String, Teacher> h = new HashMap<>();
        h.put("xiaoming", new Teacher("小明", 27));
        h.put("xiaohong", new Teacher("小洪", 32));
        h.put("xiaoliang", new Teacher("小亮", 22));
        Set<Map.Entry<String, Teacher>> entries = h.entrySet();
        Iterator<Map.Entry<String, Teacher>> iterator = entries.iterator();
        while(iterator.hasNext()){
            Map.Entry<String, Teacher> next = iterator.next();
            System.out.println(next.getKey()+"-"+next.getValue());
        }
    }
}
class Teacher{
    private String name;
    private int age;

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
5.2.4 运行截图

在这里插入图片描述

6 泛型的注意事项

6.1 泛型一定是引用数据类型,不能是基本数据类型

ArrayList<Integer>  arr= new ArrayList<>();ArrayList<int>  arr= new ArrayList<>();

6.2 在给泛型指定具体类型后,可以传入该类型或者其子类类型

import java.util.ArrayList;
public class Generic05 {
    public static void main(String[] args) {
        Pig<A> aPig = new Pig<A>(new A());
        //泛型是A类型,实参传过去的是A类型的子类型对象也是可以的
        Pig<A> bPig = new Pig<A>(new B());
    }
}
class A{}
class B extends A{}
class Pig<E>{
    E s;//E表示s的数据类型.该数据类型在定义A对象的时候指定,即在编译期间,就确定了

    public Pig(E s) {
        this.s = s;
    }
}

6.3 泛型的两种写法(推荐使用第二种)

6.3.1 左右两边全写
 ArrayList<Integer>  arr= new ArrayList<Integer>();
6.3.2 只写左边,不写右边
 //实际开发中,往往采用这种
//编译器会进行类型推断,会默认把右边<>的类型和左边<>的类型保持一致
ArrayList<Integer>  arr= new ArrayList<>();

6.4 如果没有给泛型指定数据类型,那么默认就是Object类型

 ArrayList  arr= new ArrayList();
 //本质上等价于下面这种写法
ArrayList<Object>  arr= new ArrayList<Object>();

7 泛型的经典习题

7.1 题目内容

定义Employee类
    ①该类中包含 private成员变量name,sal,birthday 其中birthday的类型为MyDate对象类型
    ③为每个属性定义get和set方法
    ③重写toString方法输出name,sal,birthday
    ④定义有参构造
定义MyDate方法
①private成员变量month,day,year
②为每个属性定义get和set方法
③重写toString方法输出month,day,year
题目要求
创建Employee类的三个对象,并放入ArrayList集合中(泛型定义),对集合元素进行排序并输出
排序要求: 调用ArrayList的sort方法,传入Comparator对象
先按照name排序,如果name相同,就按照生日日期的先后进行排序

7.2 示例代码

7.2.1 Employee类
public class Employee{
    private String name;
    private double sal;
    private MyDate birthday;

    public Employee() {
    }

    public Employee(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 getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "\nEmployee{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", birthday=" + birthday +
                '}';
    }
}
7.2.2 MyDate类
public class MyDate{
    private int month;
    private int day;
    private int year;

    public MyDate() {
    }

    public MyDate(int month, int day, int year) {
        this.month = month;
        this.day = day;
        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;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    @Override
    public String toString() {
        return "MyDate{" +
                "month=" + month +
                ", day=" + day +
                ", year=" + year +
                '}';
    }
}

7.2.3 GenericTest类

import java.util.ArrayList;
import java.util.Comparator;


public class GenericTest {
    public static void main(String[] args) {
        ArrayList<Employee> arr = new ArrayList<Employee>();
        arr.add(new Employee("张三",2000,new MyDate(2,12,1999)));
        arr.add(new Employee("李四",4000,new MyDate(3,6,2005)));
        arr.add(new Employee("张三",8000,new MyDate(1,15,1970)));
        arr.sort(new Comparator<Employee>() {
            //先按照name排序,如果nam值相同,按照日期的先后顺序排序
            @Override
            public int compare(Employee o1, Employee o2) {
                if(!(o1 instanceof Employee && o2 instanceof Employee)){
                    System.out.println("类型不正确");
                    return 0;
                }
                //比较name
                int i = o1.getName().compareTo(o2.getName());
                if(i!=0){
                    return i;
                }
                //如果name相同,比较的就是year
                int yearMinus = o1.getBirthday().getYear() - o2.getBirthday().getYear();
                if(yearMinus!=0){
                    return yearMinus;
                }
                //如果year相同,就比较month
                int monthMinus = o1.getBirthday().getMonth() - o2.getBirthday().getMonth();
                if(monthMinus!=0){
                    return monthMinus;
                }
                //如果month相同,就比较day
                return o1.getBirthday().getDay()-o2.getBirthday().getDay();
            }
        });
        System.out.println("排序后的数组"+arr);
    }
}

7.3 运行截图

在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SSS4362

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值