Java集合进阶——泛型

发布于:2024-04-19 ⋅ 阅读:(29) ⋅ 点赞:(0)

1.泛型

 介绍:

        泛型可以在编译阶段约束操作的数据类型,并进行检查。

应用场景:

        如果在定义类、方法、接口的时候,如果类型不确定,就可以使用泛型。

格式:

        <数据类型>

注意:

        泛型只支持引用数据类型

如下图中<String>,就是泛型

细节:

        1.指定泛型的具体类型后,传递数据时,可以传入该类型或者其子类类型

        2.如果不写泛型,类型默认为Object

好处:

        1.统一数据类型

        2.把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为在编译阶段类型就能确定下来

扩展:

        Java中的泛型为伪泛型,即若使用泛型确定类型后,元素若要存入集合,泛型就会检查是否为规定的类,存入集合中时,元素为Object类,但是获取元素时代码底层会将Object类强转成泛型规定的类。

        且编译时会擦除泛型,在class文件中,集合中的元素仍为Object类。

2.泛型类

        泛型类即在类名后面添加泛型约束的类。

下面创建一个泛型类

代码演示:
泛型类MyArratList:
public class MyArrayList <E> {

    Object[] obj = new Object[10];
    int size;

    public boolean add(E e) {
        obj[size] = e;
        size++;
        return true;
    }

    public E get(int index) {
        return (E) obj[index];
    }

    @Override
    public String toString() {
        return Arrays.toString(obj);
    }
}
测试类GenericsDemo:
public class GenericsDemo {
    public static void main(String[] args) {
        MyArrayList<Integer> list = new MyArrayList<>();

        list.add(111);
        list.add(222);
        list.add(333);

        System.out.println(list);

        System.out.println(list.get(1));

    }
}
运行结果:

3.泛型方法

介绍:

        泛型方法有两种形式,一种是泛型类中的方法都可以使用类名后定义的泛型,第二种是在方法申明上定义自己的泛型(只有本方法能用)下面详细介绍第二种形式。

格式:

修饰符 <类型> 返回值类型 方法名(类型 变量名){

}

小练习:

        定义一个工具类ListUtil,类中定义一个静态方法addAll,用来添加多个集合元素

代码:
ListUtil类:
public class ListUtil {
    //因为是工具类,不需要构造方法
    private ListUtil(){}

    public static <E> void addAll(ArrayList<E> list,E...e) {
        for (E element : e) {
            list.add(element);
        }
    }
}
测试类Test:
public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        ListUtil.addAll(list,"aaa", "bbb", "ccc");
        System.out.println(list);
    }
}
运行结果:

4.泛型接口

        当借口中类型不确定时,就可以使用泛型接口

格式:

        修饰符 interface 接口名<类型>{

}

使用方法:
方法一.实现类给出具体类型
代码演示:

演示代码具体类型为String

List<String>即为泛型接口,重写List中的方法后,其中的泛型方法类型也被指定为String

public class MyArrayList2 implements List<String> {
    @Override
    public int size() {
        return 0;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    @Override
    public boolean contains(Object o) {
        return false;
    }

    @Override
    public Iterator<String> iterator() {
        return null;
    }

    @Override
    public Object[] toArray() {
        return new Object[0];
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return null;
    }

    @Override
    public boolean add(String s) {
        return false;
    }

    @Override
    public boolean remove(Object o) {
        return false;
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        return false;
    }

    @Override
    public boolean addAll(Collection<? extends String> c) {
        return false;
    }

    @Override
    public boolean addAll(int index, Collection<? extends String> c) {
        return false;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        return false;
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return false;
    }

    @Override
    public void clear() {

    }

    @Override
    public String get(int index) {
        return null;
    }

    @Override
    public String set(int index, String element) {
        return null;
    }

    @Override
    public void add(int index, String element) {

    }

    @Override
    public String remove(int index) {
        return null;
    }

    @Override
    public int indexOf(Object o) {
        return 0;
    }

    @Override
    public int lastIndexOf(Object o) {
        return 0;
    }

    @Override
    public ListIterator<String> listIterator() {
        return null;
    }

    @Override
    public ListIterator<String> listIterator(int index) {
        return null;
    }

    @Override
    public List<String> subList(int fromIndex, int toIndex) {
        return null;
    }
}

方法二.实现类延续泛型,创建对象时再确定
代码演示:

这种情况下重写的List方法中使用泛型的继续使用类名后定义的泛型

public class MyArrayList3<E> implements List<E> {
    @Override
    public int size() {
        return 0;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    @Override
    public boolean contains(Object o) {
        return false;
    }

    @Override
    public Iterator<E> iterator() {
        return null;
    }

    @Override
    public Object[] toArray() {
        return new Object[0];
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return null;
    }

    @Override
    public boolean add(E e) {
        return false;
    }

    @Override
    public boolean remove(Object o) {
        return false;
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        return false;
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        return false;
    }

    @Override
    public boolean addAll(int index, Collection<? extends E> c) {
        return false;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        return false;
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return false;
    }

    @Override
    public void clear() {

    }

    @Override
    public E get(int index) {
        return null;
    }

    @Override
    public E set(int index, E element) {
        return null;
    }

    @Override
    public void add(int index, E element) {

    }

    @Override
    public E remove(int index) {
        return null;
    }

    @Override
    public int indexOf(Object o) {
        return 0;
    }

    @Override
    public int lastIndexOf(Object o) {
        return 0;
    }

    @Override
    public ListIterator<E> listIterator() {
        return null;
    }

    @Override
    public ListIterator<E> listIterator(int index) {
        return null;
    }

    @Override
    public List<E> subList(int fromIndex, int toIndex) {
        return null;
    }
}

5.泛型通配符

作用:

        可以限制类型的范围

应用场景:

        如果类型不确定,但是知道传递的都是哪个继承体系中的,就可以使用泛型的通配符

格式:

        ? extend E                表示可以传递E和E的所有子类类型

        ? super E                  表示可以传递E和E的所有父类类型

代码演示:
public class GenericsDemo2 {
    public static void main(String[] args) {
        //创建Ye Fu Zi的集合
        ArrayList<Ye> list1 = new ArrayList<>();
        ArrayList<Fu> list2 = new ArrayList<>();
        ArrayList<Zi> list3 = new ArrayList<>();
        //调用方法
        method(list1);
        method(list2);
        method(list3);


    }
    //定义方法在集合中调用对象
    public static void method(ArrayList<? extends Ye> list){
        System.out.println(list);
    }

    //创建最高父类爷
    class Ye{}
    //创建父继承爷
    class Fu extends Ye{}
    //创建子继承父
    class Zi extends Fu{}
}
运行结果:
 

也可以把上述method方法中的泛型通配符改成<? super Zi> 和上述代码效果一样。


网站公告

今日签到

点亮在社区的每一天
去签到