4-Collection、List、Iterator和泛型

文章目录


目录

提示:这里介绍Collection、LIst和泛型的基本知识点


提示:以下是本篇文章正文内容,下面案例可供参考

一、Collection集合

1、集合的概述

1.1、概述:

集合其实就是一种容器,可以用来存储多个引用类型的数据

1.2、分类: 单列集合,双列集合:

- 单列集合: 以单个单个元素进行存储
- 双列集合: 以键值对的方式进行存储

1.3、集合与数组的区别:

- 长度:
  - 数组长度是固定的
  - 集合长度是不固定的
- 存储范围:
  - 数组可以存储基本类型+引用类型 eg; int[],String[]
  - 集合只能存储引用类型,如果要存储基本类型,需要存储基本类型对应的包装类类型 eg; 				
  - ArrayList<String> ,ArrayList<Integer>

2、单列集合常用的继承体系

2.1、单列集合: 以单个单个元素进行存储

- 单列集合继承体系:

2.2、Collection接口是所有单列集合的根接口,也就意味着所有的单列集合都实现了Collection接口

- List接口继承Collection接口: List集合元素有索引,元素存取有序,元素可重复
  - ArrayList类: 数组存储结构, 查询快,增删慢
  - LinkedList类: 链表存储结构,查询慢,增删快
  - ......
- Set接口继承Collection接口:  Set集合元素没有索引 , 元素不可重复(唯一)
  - HashSet类:  哈希表结构,由哈希表保证元素唯一,元素存取无序,不可以排序
    - LinkedHashSet类:: 链表+哈希表结构,由哈希表保证元素唯一,由链表保证元素存取有序,不可以排序
  - TreeSet类: 二叉树结构,可以对元素进行排序
  - ......

单列集合常用的继承体系

3、Collection的常用功能

3.1、Collection是接口,只能通过其子类创建对象

3.2、Collection是所有单列集合的顶层父接口,所以所有单列集合都拥有Collection中的方法

3.3、常用方法:

  - `public boolean add(E e)`:  把给定的对象添加到当前集合中 。
  - `public void clear()` :清空集合中所有的元素。
  - `public boolean remove(E e)`: 把给定的对象在当前集合中删除。
  - `public boolean contains(Object obj)`: 判断当前集合中是否包含给定的对象。
  - `public boolean isEmpty()`: 判断当前集合是否为空。
  - `public int size()`: 返回集合中元素的个数。
  - `public Object[] toArray()`: 把集合中的元素,存储到数组中
public class Test {
    public static void main(String[] args) {
        // 创建Collection集合对象,限制集合元素类型为String类型
        Collection<String> col = new ArrayList<>();

        // - public boolean add(E e):  把给定的对象添加到当前集合中 。
        col.add("王宝强");
        col.add("贾乃亮");
        col.add("谢霆锋");
        col.add("陈羽凡");
        System.out.println("col:" + col);// col:[王宝强, 贾乃亮, 谢霆锋, 陈羽凡]

        // - public void clear() :清空集合中所有的元素。
        // col.clear();
        // System.out.println("col:" + col);// col:[]

        // - public boolean remove(E e): 把给定的对象在当前集合中删除。
        boolean res1 = col.remove("谢霆锋");
        System.out.println("col:" + col);// col:[王宝强, 贾乃亮, 陈羽凡]
        System.out.println("res1:" + res1);// res1: true

        // - public boolean contains(Object obj): 判断当前集合中是否包含给定的对象。
        boolean res2 = col.contains("贾乃亮");
        boolean res3 = col.contains("谢霆锋");
        System.out.println("res2:" + res2);// res2: true
        System.out.println("res3:" + res3);// res3: false

        // - public boolean isEmpty(): 判断当前集合是否为空。如果集合中没有元素返回true,否则返回false
        boolean res4 = col.isEmpty();
        System.out.println("res4:" + res4);// res4: false
        // 清空集合中的所有元素
        // col.clear();
        // boolean res5 = col.isEmpty();
        // System.out.println("res5:" + res5);// res5: true

        // - public int size(): 返回集合中元素的个数。
        System.out.println("集合元素的个数:" + col.size());// 3

        // - public Object[] toArray(): 把集合中的元素,存储到数组中
        Object[] arr = col.toArray();
        System.out.println("arr:"+ Arrays.toString(arr));// arr:[王宝强, 贾乃亮, 陈羽凡]

    }
}

二、List

1.List接口的介绍

- List接口的概述
  - java.util.List接口继承自Collection接口,是单列集合的一个重要分支
- List接口的特点
  - 它是一个元素存取有序的集合
  - 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素
  - 集合中可以有重复的元素 

2、List中的常用方法

List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,
而且还增加了一些根据元素索引来操作集合的特有方法,如下:
  • public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
  • public E get(int index):返回集合中指定位置的元素。
  • public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
  • public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

List集合特有的方法都是跟索引相关;

List接口新增常用方法的使用:
public class Test {
    public static void main(String[] args) {
        // 创建List集合对象,限制集合元素的类型为String
        List<String> list = new ArrayList<>();

        // 往集合中添加元素的方法
        list.add("马蓉");
        list.add("李小璐");
        list.add("张柏芝");
        list.add("白百何");
        System.out.println("list:" + list);// list:[马蓉, 李小璐, 张柏芝, 白百何]

        // - public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
        list.add(1, "潘金莲");
        System.out.println("list:" + list);// list:[马蓉, 潘金莲, 李小璐, 张柏芝, 白百何]

        // - public E get(int index):返回集合中指定位置的元素。
        String e = list.get(1);
        System.out.println("e:" + e);// e:潘金莲

        // - public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
        String removeE = list.remove(1);
        System.out.println("被删除的元素:"+removeE);// 被删除的元素:潘金莲
        System.out.println("list:" + list);// list:[马蓉, 李小璐, 张柏芝, 白百何]

        // - public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
        String setE = list.set(2, "董洁");
        System.out.println("被替换的元素:"+setE);// 被替换的元素:张柏芝
        System.out.println("list:" + list);// list:[马蓉, 李小璐, 董洁, 白百何]
    }
}

注意: 如果集合元素为Integer类型,那么删除的时候优先根据索引删除:

public class Test2 {
    public static void main(String[] args) {
        /*
            public boolean remove(Object obj): 删除指定的元素。
            public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
         */
        // 创建List集合,限制集合元素的类型为Integer
        List<Integer> list = new ArrayList<>();

        // 往集合中添加元素
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        // 删除元素
        list.remove(2);// 优先根据索引删除
        System.out.println("list:" + list);// list:[1, 2, 4]
    }
}

3、List的子类

- ArrayList集合: 底层采用的是数组结构,查询快,增删慢
  - 方法: 来自Collection,List
- LinkedList集合; 底层采用的是链表结构,查询慢,增删快
  - 方法: 来自Collection,List,LinkedList特有的方法
  - 特有的方法:
public void addFirst(E e):将指定元素插入此列表的开头
public void addLast(E e):将指定元素添加到此列表的结尾
public E getFirst():返回此列表的第一个元素
public E getLast():返回此列表的最后一个元素
public E removeFirst():移除并返回此列表的第一个元素
public E removeLast():移除并返回此列表的最后一个元素
public E pop():从此列表所表示的堆栈处弹出一个元素
public void push(E e):将元素推入此列表所表示的堆栈
public class Test {
    public static void main(String[] args) {
        // 创建LinkedList集合,限制集合元素类型为String
        LinkedList<String> list = new LinkedList<>();

        // 往集合中添加一些元素
        list.add("苍老师");
        list.add("小泽老师");
        list.add("波老师");
        System.out.println("list:"+list);// list:[苍老师, 小泽老师, 波老师]

        // public void addFirst(E e):将指定元素插入此列表的开头
        list.addFirst("吉泽老师");// list:[吉泽老师, 苍老师, 小泽老师, 波老师]
        System.out.println("list:"+list);// list:[吉泽老师, 苍老师, 小泽老师, 波老师]

        // public void addLast(E e):将指定元素添加到此列表的结尾
        list.addLast("三村老师");
        System.out.println("list:"+list);// list:[吉泽老师, 苍老师, 小泽老师, 波老师, 三村老师]

        // public E getFirst():返回此列表的第一个元素
        System.out.println("第一个元素: "+list.getFirst());// 吉泽老师

        // public E getLast():返回此列表的最后一个元素
        System.out.println("最后一个元素: "+list.getLast());// 三村老师

        // public E removeFirst():移除并返回此列表的第一个元素
        String removeFirstE = list.removeFirst();
        System.out.println("removeFirstE:"+removeFirstE);// 吉泽老师

        // public E removeLast():移除并返回此列表的最后一个元素
        String removeLastE = list.removeLast();
        System.out.println("removeLastE:"+removeLastE);// 三村老师
        System.out.println("list:"+list);// list:[苍老师, 小泽老师, 波老师]


        // public E pop():从此列表所表示的堆栈处弹出一个元素(removeFirst方法)
        String popE = list.pop();
        System.out.println("popE:"+popE);// 苍老师

        // public void push(E e):将元素推入此列表所表示的堆栈(addFirst)
        list.push("明日花老师");
        System.out.println("list:"+list);// list:[明日花老师, 小泽老师, 波老师]

    }
}

三、Iterator迭代器

1、Iterator接口

1.1、迭代的概念

1.1.1、概述:迭代即Collection集合元素的通用获取方式。
 	在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续再判断,
 	如果还有就再取出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
1.1.2、迭代的步骤:
  - 获取迭代器对象
  - 使用迭代器对象判断集合中是否有元素可以取出
  - 如果有元素可以取出,就直接取出来该元素,如果没有元素可以取出,就结束迭代
1.1.3、获取迭代器对象

Collection集合提供了一个获取迭代器的方法:

  • public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。
Iterator迭代器对象的常用方法
  • public boolean hasNext():如果仍有元素可以迭代,则返回 true。
  • public E next():返回迭代的下一个元素。
  • void remove()删除当前迭代出来的元素
案例:
public class Test {
    public static void main(String[] args) {
        /*
            获取迭代器对象
                Collection集合提供了一个获取迭代器的方法:
                - public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。

            Iterator迭代器对象的常用方法
                - public boolean hasNext():如果仍有元素可以迭代,则返回 true。
                - public E next():返回迭代的下一个元素。
                - void remove()删除当前迭代出来的元素
         */
        Collection<String> col = new ArrayList<>();

        // 往集合中添加元素
        col.add("王宝强");
        col.add("贾乃亮");
        col.add("谢霆锋");
        col.add("陈羽凡");

        // 通过集合对象获取对应的迭代器对象
        Iterator<String> it = col.iterator();

        // 循环判断是否有元素可以迭代
        while (it.hasNext()) {
            // 如果有,就在循环中取出可以迭代的元素
            String e = it.next();
            System.out.println("元素:"+e);

            // 需求:如果迭代出来的元素是谢霆锋,就删除该元素
            if ("谢霆锋".equals(e)){
                it.remove();
            }
        }

        System.out.println("col:"+col);// col:[王宝强, 贾乃亮, 陈羽凡]
    }
}

2、Iterator实现原理

2.1、 迭代器的实现原理:

​ 我们在之前案例已经完成了Iterator遍历集合的整个过程。当遍历集合时,首先通过调用集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。

​ Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素。在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。

2.2、原理图:

在这里插入图片描述

3、Itrator的常见问题

3.1、常见问题1:

在进行集合元素获取时,如果集合中已经没有元素可以迭代了,还继续使用迭代器的next方法,
将会抛出java.util.NoSuchElementException没有集合元素异常。
案例:
	public class Test2 {
    public static void main(String[] args) {
        /*
            问题一:在进行集合元素获取时,如果集合中已经没有元素可以迭代了,
                  还继续使用迭代器的next方法,将会抛出java.util.NoSuchElementException没有集合元素异常。
         */
        Collection<String> col = new ArrayList<>();

        // 往集合中添加元素
        col.add("王宝强");
        col.add("贾乃亮");
        col.add("谢霆锋");
        col.add("陈羽凡");

        // 获取迭代器对象
        Iterator<String> it = col.iterator();

        // 迭代--->快捷键:itit
        while (it.hasNext()) {
            String e = it.next();
            System.out.println("元素:" + e);
        }

        System.out.println("--------");
        // 调用next方法
        // String next = it.next();// 报NoSuchElementException没有找到元素异常
        // System.out.println("next:" + next);

        // 需求:再迭代col集合中所有的元素
        // 获取迭代器对象
        Iterator<String> it1 = col.iterator();

        // 迭代--->快捷键:itit
        while (it1.hasNext()) {
            String e = it1.next();
            System.out.println("元素:" + e);
        }

    }
}

解决方法:使用集合从新获取一个新的迭代器对象来使用

3.2、常见问题2:

在进行集合元素迭代时,如果添加或移除集合中的元素 , 将无法继续迭代 , 
将会抛出ConcurrentModificationException并发修改异常.
案例:
	public class Test3 {

    public static void main(String[] args) {
        /*
            问题: 在进行集合元素迭代时,如果添加或移除集合中的元素,将无法继续迭代,将会抛出ConcurrentModificationException并发修改异常.
         */
        Collection<String> col = new ArrayList<>();

        // 往集合中添加元素
        col.add("王宝强");
        col.add("贾乃亮");
        col.add("谢霆锋");
        col.add("陈羽凡");

        // 获取迭代器对象
        Iterator<String> it = col.iterator();

        // 迭代
        while (it.hasNext()) {
            String e = it.next();
            // 问题一: 迭代一个元素,就使用集合对象往集合中添加一个元素
            // col.add("itheima");// 报并发修改异常

            // 问题二: 迭代一个元素,就使用集合对象删除一个元素
            // col.remove(e);// 报并发修改异常

            // 迭代器可以一边迭代一边删除
            it.remove();
        }
        System.out.println("col:" + col);// col:[]

    }
}

解决办法:

  • 使用CopyOnWriteArrayList集合,就可以迭代的时候,往集合中添加或删除元素
  • 使用迭代器的remove方法实现一边迭代,一边删除

4、增强for循环

4.1、概述:

增强for循环(foreach循环),是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和Collection集合

4.2、原理:

内部基于Iterator迭代器实现,所以在遍历的过程中,不能对集合中的元素进行增删操作,
否则抛出ConcurrentModificationException并发修改异常 

4.3、格式:

for(数据类型 变量名 : 数组名\集合名){
}

案例:
	public class Test4 {
    public static void main(String[] args) {
        /*
            for(数据类型 变量名 :  数组名\集合名){

            }
         */
        // 需求1: 增强for循环遍历集合元素
        Collection<String> col = new ArrayList<>();

        // 往集合中添加元素
        col.add("王宝强");
        col.add("贾乃亮");
        col.add("谢霆锋");
        col.add("陈羽凡");

        // 快捷键: 集合名.for
        for (String e : col) {
            System.out.println("e:" + e);
        }

        System.out.println("--------");

        // 需求1: 增强for循环遍历数组元素
        String[] arr = {"王宝强",
                "贾乃亮",
                "谢霆锋",
                "陈羽凡"};

        // 快捷键: 数组名.for
        for (String e : arr) {
            System.out.println("e:" + e);
        }
    }
}

四、泛型

1、泛型的概述

1.1、概述:

JDK5之后,新增了泛型(Generic)语法,可以在类、接口或方法中预支地使用未知的类型
简而言之: 泛型其实就是表示一种未知的数据类型,在使用的时候确定其具体的数据类型
表示方式:  <泛型变量>

1.2、泛型的好处:

- 将运行时期的ClassCastException,转移到了编译时期变成了编译失败
- 避免了类型转换的麻烦

1.3、集合不使用泛型:

- 可能会发生类型转换异常
- 避免类型转换异常,就需要先做类型判断,再转型--->比较麻烦
public class Test1 {
    public static void main(String[] args) {
        // 注意: 不指定集合元素的类型,元素的类型默认是Object类型

        // 创建ArrayList集合对象,不指定泛型的具体数据类型
        ArrayList list = new ArrayList();

        // 往集合中添加元素
        list.add("itheima");
        list.add(666);
        list.add(3.14);
        list.add(true);
        list.add("itcast");
        System.out.println("list:"+list);// list:[itheima, 666, 3.14, true, itcast]

        // 获取集合中所有字符串元素的长度
        for (Object obj : list) {
            // String str = (String) obj;// 发生类型转换异常
            // System.out.println(str.length());
            
            // 转换类型之前先判断
            if (obj instanceof String){
                String str = (String) obj;
                System.out.println(str.length());
            }
        }
    }
}

1.4、集合使用泛型

- 概述:指定泛型的具体数据类型----->(只能是引用数据类型)
public class Test2{
    public static void main(String[] args) {
        // 注意: 使用集合的时候,建议通过泛型来限制集合元素类型一致
        
        // 创建ArrayList集合对象,指定泛型的具体数据类型为String
        ArrayList<String> list = new ArrayList<>();

        // 往集合中添加元素
        list.add("itheima");
        // list.add(666);// 编译报错,把运行时的类型转换异常,转移到了编译时期变成了编译失败
        // list.add(3.14);// 编译报错,把运行时的类型转换异常,转移到了编译时期变成了编译失败
        // list.add(true);// 编译报错,把运行时的类型转换异常,转移到了编译时期变成了编译失败
         list.add("itcast");
        System.out.println("list:"+list);// list:[itheima, itcast]

        // 获取集合中所有字符串元素的长度
        for (String s : list) {
            System.out.println(s.length());
        }
    }
}

2、定义和使用泛型的类

2.1、定义含有泛型的类

格式:
public class 类名<泛型变量>{
    
}
泛型变量: 可以是任意字母,eg: A,B,E,...a,b,....;一般写E
// 含有泛型的类
public class MyGenericClass1<E> {
 
    E e;
    
    public void method1(E e) {
        System.out.println("e的类型:" + e.getClass());
    }
    
    public E method2(E e){
        return e;
    }
}

2.2、使用含有泛型的类

public class Test {
    public static void main(String[] args) {
        // 使用含有泛型的类
        // 创建含有泛型的类的对象
        MyGenericClass1<String> mc1 = new MyGenericClass1<>();
        mc1.method1("itheima");

        // 创建含有泛型的类的对象
        MyGenericClass1<Integer> mc2 = new MyGenericClass1<>();
        mc2.method1(100);


    }
}

3、定义和使用泛型的方法

3.1、定义含有泛型的方法

- 格式:
  修饰符 <泛型变量> 返回值类型 方法名(形参列名){
      方法体
  }
  // 泛型变量:可以写任意字母,一般写T

3.2、使用含有泛型的方法

- 调用含有泛型方法的时候,确定泛型的具体数据类型
- 案例:
public class Test {
    public static void main(String[] args) {
        // 使用含有泛型的方法:调用含有泛型的方法,指定泛型的具体数据类型
        MyGenericMethod mg = new MyGenericMethod();
        // 调用method1,指定泛型的具体类型为Integer
        Integer i = mg.method1(100);
        System.out.println("i:"+i);// i:100

        // 调用method1,指定泛型的具体类型为String
        String str = mg.method1("itheima");
        System.out.println("str:"+str);// str:itheima

    }
}

4、定义和使用泛型的接口

4.1、定义含有泛型的接口

- 格式:
- public interface 接口名<泛型变量>{
}
// 泛型变量:可以是任意字母,一般写E
// 含有泛型的接口
public interface MyGenericInterface<E> {
    
    void method1(E e);
    
    public default E method2(E e){
        return e;
    }
    
    
}

4.2、使用含有泛型的接口**

- 方式一: 实现类实现接口的时候,确定接口泛型的具体数据类型
  - 格式:
  - public class 类名 implements 接口名<具体的引用数据类型>{}
// 实现接口的时候,确定接口泛型的具体数据类型
class Imp implements MyGenericInterface<String>{

    @Override
    public void method1(String s) {
        System.out.println("method1.."+s);
    }

    @Override
    public String method2(String s) {
        System.out.println("method2..."+s);
        return s;
    }
}
方式二:
实现类实现接口的时候,不确定接口泛型的具体数据类型,而是创建实现类对象的时候确定泛型的具体数据类型

- 格式:
- public class 类名<泛型变量> implements 接口名<泛型变量>{}
// 实现类实现接口的时候,不确定接口泛型的具体数据类型,而是创建实现类对象的时候确定泛型的具体数据类型
class Imp2<E> implements MyGenericInterface<E>{

    @Override
    public void method1(E e) {
        System.out.println("e的类型:"+e.getClass());
    }

    @Override
    public E method2(E e) {
        System.out.println("e的类型:"+e.getClass());
        return e;
    }
}

public class Test {
    public static void main(String[] args) {
        // 接口: 被实现
        // 创建实现类对象的时候确定泛型的具体数据类型
        Imp2<String> i1 = new Imp2<>();
        i1.method1("itheima");
        String res1 = i1.method2("itcast");

        System.out.println("-----");
        
        Imp2<Integer> i2 = new Imp2<>();
        i2.method1(100);
        Integer res2 = i2.method2(200);

    }
}

5、泛型通配符

5.1、 概述: 泛型通配符用问号表示(?)

5.2、为什么需要泛型通配符:

  - 泛型本身不存在继承关系,不可以给已指定泛型的变量接收有其他泛型类型的对象
    - `Collection<Object> list = new ArrayList<String>(); //错误格式,泛型不存在继承关系`
  - 如果想要使变量在未来接收有泛型定义的对象,又不确定泛型要定义的类型可以使用泛型通配符
    - `Collection<?> list 变量接收`

5.3、通配符基本使用

  - 格式: `数据类型<?> 变量`
  - 注意:
    - 如果使用了泛型通配符,那么该集合变量元素类型默认是Object类型
    - 如果使用了泛型通配符,那么该集合变量只能取元素,无法增删元素
public class Test {
    public static void main(String[] args) {
        // Integer继承Number,Number继承Object,String继承Object
        ArrayList<Object> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        ArrayList<Integer> list3 = new ArrayList<>();
        ArrayList<Number> list4 = new ArrayList<>();

        // 泛型本身不存在继承关系,不可以给已指定泛型的变量接收有其他泛型类型的对象
        // method1(list1);// 编译报错
        // method1(list2); // 正确
        // method1(list3);// 编译报错
        // method1(list4);// 编译报错

        method2(list1);
        method2(list2);
        method2(list3);
        method2(list4);
    }

    // 定义一个方法,可以接收任意ArrayList集合对象
    // 如果想要使变量在未来接收有泛型定义的对象,又不确定泛型要定义的类型可以使用泛型通配符
    public static void method2(ArrayList<?> list) {// 已指定泛型的变量
        System.out.println("执行了");
        // 注意: 如果使用了泛型通配符,那么该集合元素类型默认是Object类型
        for (Object obj : list) {

        }
        // 注意: 如果使用了泛型通配符,那么该集合变量只能取元素,无法增加元素
         // list.add(1000);// 编译报错
        list.remove(1000)}

    public static void method1(ArrayList<String> list) {// 已指定泛型的变量

    }
}

5.4、通配符高级使用----受限泛型

- 上限: 
  - 格式: `<? extends 类名>`
  - 表示: 只接受该类类型或者其子类类型
- 下限:
  - 格式: `<? super 类名>`
  - 表示: 只接受该类类型或者其父类类型
public class Test {
    public static void main(String[] args) {
        // Integer继承Number,Number继承Object,String继承Object
        ArrayList<Object> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        ArrayList<Integer> list3 = new ArrayList<>();
        ArrayList<Number> list4 = new ArrayList<>();

        method1(list1);
        //method1(list2);// 编译报错
        method1(list3);
        method1(list4);
        
        //method2(list1);// 编译报错
        //method2(list2);// 编译报错
        method2(list3);
        method2(list4);

    }

    // 定义一个方法,只可以接收泛型是Integer或者其父类类型的ArrayList集合对象
    public static void method1(ArrayList<? super Integer> list){
        list.add(100);
    }

    // 定义一个方法,只可以接收泛型是Number或者其子类类型的ArrayList集合对象
    public static void method2(ArrayList<? extends Number> list){
  
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值