[20]-泛型

本来想不放在集合中说,但是看了一下,集合中用泛型的地方太多,所以就加入进来

为什么需要使用泛型

起因:JDK1.4 以前类型不明确:装入集合的类型都被当作 Object 对待,从而失去自己的实际 类型。从集合中取出时往往需要转型,效率低,容易产生错误。

解决办法:

泛型,在定义集合的时候同时定义集合中对象的类型

好处:

增强程序的可读性和安全性

实际开发中,我们多用泛型指定集合元素的类型,下面的内容可以作为了解

泛型的分类

(1)泛型类

(2)泛型接口

(3)泛型方法

泛型类

/**
 * 泛型类  在使用类创建对象的时候对创建的对象类型做约束,如果用英文字母代替,则创建的时候需要指定数据类型
 */
public class TestGeneric {
    public static void main(String[] args) {
        MyGeneric<String> generic1 = new MyGeneric<>();//1.8后后面的泛型可以省略,这里是String类型
        MyGeneric<Integer> generic2 = new MyGeneric<Integer>();//这里是Integer类型
    }
}

class MyGeneric<T>{//T只是一个英文字母,代表一种数据类型,具体的数据类型只有创建类的对象的时候才能指定

}

泛型接口

/**
 * 泛型接口
 * 对实现类的数据类型做约束
 * 一般使用英文字母时,在实现类实现接口时定义
 * @param <T>
 */
public interface TestGenericInterface<T> { //泛型接口的类型是在实现类的时候定义的

}
/*
如果知道实现类是代表什么类型,可以直接指定
 */
class MyImplement implements TestGenericInterface<String>{

}

/*
如果不知道实现类是什么类型,那么实现类也需要定义字母代替类型的泛型
 这个泛型类型由实现类创建对象时决定
 */
class MyImplement2<T> implements TestGenericInterface<T>{

}
class TestGenericInterface1{
    public static void main(String[] args) {
        MyImplement m1 = new MyImplement();//由于指定了类型,所以不需要再用泛型
        MyImplement2<Integer> m2 = new MyImplement2<>();//因为没有指定泛型,所以需要定义泛型
    }
}

泛型方法

package com.lin.test;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

public class TestMethodGeneric<T> {//泛型类
    public void show(T t){ //创建MethodGeneric对象的时候决定
        System.out.println(t);
    }

    public <Q> void method(Q q){//在调用method这个方法的时候明确
        System.out.println(q);
    }

    public <K> void  fun(K...K){//可变参数的泛型方法  K...k在这是被当作数组
        for (int i = 0; i < K.length; i++) {
            System.out.println(K[i]); //根据索引来获取
        }
    }
}

test类

package com.lin.test;

public class TestMethGeneric {
    public static void main(String[] args) {

        TestMethodGeneric<String> mg = new TestMethodGeneric<>();
        mg.show("123");//因为创建对象的泛型是String类型,这里就只能是String类型

        //在有了泛型方法后,解决了参数个数相同情况下的方法重载
        mg.method("hello");
        mg.method(123);
        mg.method('a');

        //可变参数的泛型方法,解决参数的个数不同,类型不同的方法重载
        mg.fun("hello");
        mg.fun("hello","world","java");
        mg.fun(123,456);
    }
}

泛型在集合中的使用

泛型的上下限
上限:
泛型的上限 谁继承了这个类谁就能用
下限:
这个类及这个类的父类都能用

person类

重写了hashCode 和 equals方法

实现了Comparable接口 重写了其中方法

package com.lin.generic;

import java.util.Objects;

public class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person() {
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", 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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public int compareTo(Person o) {
        //重写方法,按照英文字母的升序去排序
        return this.getName().compareTo(o.getName());
    }
}

Student类

继承了Person类

package com.lin.generic;

import java.util.Objects;

public class Student extends Person {
    private String stuNO;

    public Student() {
    }

    public Student(String stuNO) {
        this.stuNO = stuNO;
    }

    public Student(String name, int age, String stuNO) {
        super(name, age);
        this.stuNO = stuNO;
    }

    public String getStuNO() {
        return stuNO;
    }

    public void setStuNO(String stuNO) {
        this.stuNO = stuNO;
    }

    @Override
    public String toString() {
        return super.toString()+"Student{" +
                "stuNO='" + stuNO + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        Student student = (Student) o;
        return Objects.equals(stuNO, student.stuNO);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), stuNO);
    }
}

1.泛型的上下限

上限:

泛型的上限 谁继承了这个类谁就能用

下限:

这个类及这个类的父类都能用

package com.lin.generic;

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {

        //创建集合对象,同时明确了集合中所有存储的对象的类型只能是Person类型
        ArrayList<Person> a1 = new ArrayList<>();
        //创建Person类型的对象添加到集合中
        Person lin = new Person("lin", 18);
        Person liang = new Person("liang", 20);
        Person chaoChaoGeGe = new Person("ChaoChaoGeGe", 20);
        //添加对象到集合中 ,
        a1.add(lin);
        a1.add(liang);
        a1.add(chaoChaoGeGe);

        //遍历
        print(a1);

        //创建一个集合对象,由于存储Student类型的对象
        ArrayList<Student> a2 = new ArrayList<>();
        //创建学生对象
        Student kankan = new Student("康康", 12, "1");
        Student maliya = new Student("玛利亚", 13, "2");
        Student jian = new Student("简", 13, "3");
        //添加到集合中
        a2.add(kankan);
        a2.add(maliya);
        a2.add(jian);

       // print(a2); 使用37-41代码报错
        // 报错,因为 相当于ArrayList<Person> a1 = new ArrayList<Student>() 泛型限定于Person 所以错误

        print(a2);//适用泛型上限方法

        //调用show方法
        show(a1);
        show(a2);


    }
    /*public static void  print(ArrayList<Person> a1) { //这里只能遍历Person 所以没有意义需要修改
        for (Person person : a1) {
            System.out.println(person);
        }
    }*/
    //泛型的上限:   Person及子类就都能用
    public static void print(ArrayList<? extends Person> a1){//泛型的上限  谁继承了person谁就能用
        for (Person person : a1) {
            System.out.println(person);
        }
    }
    //泛型的下限:  确定子类 本类及父类可使用
    public static void  show(ArrayList<? super Student> a1){
        for (Object obj : a1) {
            System.out.println(obj);
        }
    }
}

泛型在集合中的使用,泛型只在编译中生效

package com.lin.generic;

import java.util.*;

/**
 * 泛型在集合中的使用
 */
public class Test2 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("hello");

        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.add(123);//这里做了自动装箱的处理

        //存储自定对象的时候要求重写对象的hashCode()和equals()
        HashSet<Person> hashSet = new HashSet<>();
        hashSet.add(new Person("lin",18));

        //Person 对象需要具备内部或者外部比较器 就是实现
        TreeSet<Person> treeSet = new TreeSet<>();


        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("hello",123);//123做了自动装箱

        //HashMap 存储自定义对象
        HashMap<Person, String> hashMap1 = new HashMap<>();
        Person p1 = new Person("lin",18);
        hashMap1.put(p1,p1.getName());

        //TreeMap 存储自定义对象
        TreeMap<Person, Integer> treeMap = new TreeMap<>();
        treeMap.put(p1,p1.getAge());

        //泛型只在编译中起作用
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值