Java集合进阶——泛型

1.泛型

介绍:

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

应用场景:

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

格式:

<数据类型>

注意:

泛型只支持引用数据类型

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

细节:

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

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

好处:

1.统一数据类型

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

扩展:

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

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

2.泛型类

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

下面创建一个泛型类

代码演示:
泛型类MyArratList:
java 复制代码
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:
java 复制代码
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类:
java 复制代码
public class ListUtil {
    //因为是工具类,不需要构造方法
    private ListUtil(){}

    public static <E> void addAll(ArrayList<E> list,E...e) {
        for (E element : e) {
            list.add(element);
        }
    }
}
测试类Test:
java 复制代码
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

java 复制代码
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方法中使用泛型的继续使用类名后定义的泛型

java 复制代码
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的所有父类类型

代码演示:
java 复制代码
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> 和上述代码效果一样。

相关推荐
mazo_command13 分钟前
【MATLAB课设五子棋教程】(附源码)
开发语言·matlab
myNameGL16 分钟前
linux安装idea
java·ide·intellij-idea
IT猿手17 分钟前
多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码
开发语言·人工智能·算法·机器学习·matlab
青春男大17 分钟前
java栈--数据结构
java·开发语言·数据结构·学习·eclipse
88号技师18 分钟前
几款性能优秀的差分进化算法DE(SaDE、JADE,SHADE,LSHADE、LSHADE_SPACMA、LSHADE_EpSin)-附Matlab免费代码
开发语言·人工智能·算法·matlab·优化算法
Zer0_on20 分钟前
数据结构栈和队列
c语言·开发语言·数据结构
一只小bit21 分钟前
数据结构之栈,队列,树
c语言·开发语言·数据结构·c++
HaiFan.1 小时前
SpringBoot 事务
java·数据库·spring boot·sql·mysql
我要学编程(ಥ_ಥ)1 小时前
一文详解“二叉树中的深搜“在算法中的应用
java·数据结构·算法·leetcode·深度优先
music0ant1 小时前
Idea 添加tomcat 并发布到tomcat
java·tomcat·intellij-idea